diff --git a/ChangeLog b/ChangeLog index 026ff3e76..9cef9c96d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,739 @@ +2009-12-25 Robert Millan + + * term/i386/pc/at_keyboard.c + (keyboard_controller_wait_untill_ready): New function. + (grub_keyboard_controller_write, grub_keyboard_controller_read) + (keyboard_controller_led): Use keyboard_controller_wait_untill_ready() + for keyboard polling, rather than duplicate the same loop. This + saves a few bytes in code size. + +2009-12-25 Vladimir Serbinenko + + Support for (pxe[:server[:gateway]]) syntax and + use environment variable for PXE. + + * commands/i386/pc/pxecmd.c (options): Removed. + (print_ip): Removed. + (grub_cmd_pxe): Removed + (grub_cmd_pxe_unload): New function. + * fs/i386/pc/pxe.c (grub_pxe_disk_data): New structure. + (grub_pxe_your_ip): Made static. + (grub_pxe_default_server_ip): Likewise. + (grub_pxe_default_gateway_ip): Likewise. + (grub_pxe_blksize): Likewise. + (parse_ip): New function. + (grub_pxe_open): Support server and gateway specification. + (grub_pxe_close): Free disk->data. + (grub_pxefs_open): Use disk->data. + (grub_pxefs_read): Likewise. + (grub_env_write_readonly): New function. + (set_mac_env): Likewise. + (set_env_limn_ro): Likewise. + (parse_dhcp_vendor): Likewise. + (grub_pxe_detect): Set the environment variables. + (set_ip_env): New function. + (write_ip_env): Likewise. + (grub_env_write_pxe_default_server): Likewise. + (grub_env_write_pxe_default_gateway): Likewise. + (grub_env_write_pxe_blocksize): Likewise. + (GRUB_MOD_INIT(pxe)): Set environment variables. + * include/grub/i386/pc/pxe.h (grub_pxe_mac_addr): Rename to ... + (grub_pxe_mac_addr_t): ... this. All users updated. + (grub_pxe_your_ip): Removed. + (grub_pxe_server_ip): Likewise. + (grub_pxe_gateway_ip): Likewise. + (grub_pxe_blksize): Likewise. + +2009-12-25 Carles Pina i Estany + + * commands/help.c: Include `'. + (grub_cmd_help): Gettextizze. + (GRUB_MOD_INIT): Likewise. + * commands/i386/pc/play.c: Include `'. + (GRUB_MOD_INIT): Gettextizze. + * commands/search.c: Include `'. + (options): Gettextizze. + (GRUB_MOD_INIT): Gettextizze. + * lib/arg.c: Include `'. + (help_options): Gettextizze. + (find_long): Likewise. + (grub_arg_show_help): Likewise. + * normal/dyncmd.c: Include `'. + (read_command_list): Gettextizze. + * po/POTFILES: Add `commands/i386/pc/play.c', `commands/search.c', + `commands/help.c', `lib/arg.c' and `normal/dyncmd.c'. + +2009-12-25 Robert Millan + + * include/grub/i386/at_keyboard.h (NUM_LOCK, SCROLL_LOCK): New macros. + * term/i386/pc/at_keyboard.c (KEYBOARD_STATUS_NUM_LOCK) + (KEYBOARD_LED_SCROLL, KEYBOARD_LED_NUM, KEYBOARD_LED_CAPS): New macros. + (led_status): New variable. + (keyboard_controller_led): New function. + (grub_at_keyboard_getkey_noblock): Handle num lock and scroll lock, + update led status for caps lock, num lock and scroll lock. + +2009-12-25 Felix Zielcke + + * util/hostdisk.c (open_device): Fix a comment. + +2009-12-24 Robert Millan + + * util/grub-install.in (host_os): New variable. + * util/i386/efi/grub-install.in (host_os): Likewise. + +2009-12-24 Robert Millan + + * util/mkisofs/write.c (padblock_write): Abort when given an + excedingly large embed image, instead of silently truncating it. + +2009-12-24 Robert Millan + + * include/multiboot.h: Indentation fixes. + +2009-12-24 Robert Millan + + * include/multiboot.h (struct multiboot_aout_symbol_table) + (struct multiboot_elf_section_header_table): New structure + declarations (stolen from GRUB Legacy). + (struct multiboot_info): Replace opaque `syms' with a.out and ELF + table information. + + (multiboot_aout_symbol_table_t, multiboot_elf_section_header_table_t) + (multiboot_info_t, multiboot_memory_map_t, multiboot_module_t): New + type aliases. + +2009-12-24 Robert Millan + + * include/multiboot.h: Make comments src2texi-friendly. + +2009-12-24 Robert Millan + + For consistency with [multiboot]/docs/boot.S. + + * include/multiboot.h (MULTIBOOT_MAGIC): Rename from this ... + (MULTIBOOT_HEADER_MAGIC): ... to this. Update all users. + (MULTIBOOT_MAGIC2): Rename from this ... + (MULTIBOOT_BOOTLOADER_MAGIC): ... to this. Update all users. + +2009-12-24 Robert Millan + + * include/multiboot.h: Remove `'. + (multiboot_uint16_t, multiboot_uint32_t, multiboot_uint64_t): New + types. Update all users. + +2009-12-25 Carles Pina i Estany + + * commands/efi/loadbios.c: Capitalize acronyms, replace `could not' by + `couldn't' and `can not' by `cannot'. + * commands/i386/pc/drivemap.c: Likewise. + * disk/ata.c: Likewise. + * disk/ieee1275/nand.c: Likewise. + * fs/affs.c: Likewise. + * fs/fat.c: Likewise. + * fs/hfs.c: Likewise. + * fs/hfsplus.c: Likewise. + * fs/iso9660.c: Likewise. + * fs/jfs.c: Likewise. + * fs/minix.c: Likewise. + * fs/reiserfs.c: Likewise. + * fs/sfs.c: Likewise. + * fs/udf.c: Likewise. + * fs/ufs.c: Likewise. + * fs/xfs.c: Likewise. + * loader/powerpc/ieee1275/linux.c: Likewise. + * loader/sparc64/ieee1275/linux.c: Likewise. + * util/grub-probe.c: Likewise. + * util/misc.c: Likewise. + +2009-12-24 Carles Pina i Estany + + * bus/usb/usbhub.c: Fix capitalization, fullstop and newlines in + grub_errno calls. + * commands/acpi.c: Likewise. + * commands/blocklist.c: Likewise. + * commands/efi/loadbios.c: Likewise. + * commands/i386/pc/drivemap.c: Likewise. + * commands/loadenv.c: Likewise. + * commands/memrw.c: Likewise. + * commands/password.c: Likewise. + * commands/videotest.c: Likewise. + * disk/ata.c: Likewise. + * disk/ata_pthru.c: Likewise. + * disk/dmraid_nvidia.c: Likewise. + * disk/ieee1275/nand.c: Likewise. + * disk/ieee1275/ofdisk.c: Likewise. + * disk/loopback.c: Likewise. + * disk/lvm.c: Likewise. + * disk/mdraid_linux.c: Likewise. + * disk/raid.c: Likewise. + * disk/raid6_recover.c: Likewise. + * disk/scsi.c: Likewise. + * efiemu/main.c: Likewise. + * efiemu/mm.c: Likewise. + * efiemu/pnvram.c: Likewise. + * efiemu/symbols.c: Likewise. + * font/font.c: Likewise. + * fs/cpio.c: Likewise. + * fs/hfsplus.c: Likewise. + * fs/iso9660.c: Likewise. + * fs/jfs.c: Likewise. + * fs/minix.c: Likewise. + * fs/ntfs.c: Likewise. + * fs/ntfscomp.c: Likewise. + * fs/reiserfs.c: Likewise. + * fs/ufs.c: Likewise. + * fs/xfs.c: Likewise. + * gettext/gettext.c: Likewise. + * include/grub/auth.h: Likewise. + * kern/elf.c: Likewise. + * kern/file.c: Likewise. + * kern/ieee1275/init.c: Likewise. + * kern/ieee1275/mmap.c: Likewise. + * kern/ieee1275/openfw.c: Likewise. + * kern/powerpc/dl.c: Likewise. + * kern/sparc64/dl.c: Likewise. + * lib/arg.c: Likewise. + * loader/i386/bsd.c: Likewise. + * loader/i386/bsdXX.c: Likewise. + * loader/i386/efi/linux.c: Likewise. + * loader/i386/efi/xnu.c: Likewise. + * loader/i386/ieee1275/linux.c: Likewise. + * loader/i386/linux.c: Likewise. + * loader/i386/multiboot.c: Likewise. + * loader/i386/pc/linux.c: Likewise. + * loader/i386/pc/multiboot2.c: Likewise. + * loader/i386/xnu.c: Likewise. + * loader/ieee1275/multiboot2.c: Likewise. + * loader/macho.c: Likewise. + * loader/machoXX.c: Likewise. + * loader/multiboot2.c: Likewise. + * loader/multiboot_loader.c: Likewise. + * loader/powerpc/ieee1275/linux.c: Likewise. + * loader/sparc64/ieee1275/linux.c: Likewise. + * loader/xnu.c: Likewise. + * loader/xnu_resume.c: Likewise. + * mmap/i386/pc/mmap.c: Likewise. + * normal/menu_viewer.c: Likewise. + * partmap/acorn.c: Likewise. + * partmap/amiga.c: Likewise. + * partmap/apple.c: Likewise. + * script/lexer.c: Likewise. + * term/gfxterm.c: Likewise. + * term/i386/pc/serial.c: Likewise. + * term/i386/pc/vga.c: Likewise. + * term/ieee1275/ofconsole.c: Likewise. + * term/terminfo.c: Likewise. + * video/bitmap.c: Likewise. + * video/efi_gop.c: Likewise. + * video/efi_uga.c: Likewise. + * video/fb/video_fb.c: Likewise. + * video/i386/pc/vbe.c: Likewise. + * video/readers/tga.c: Likewise. + * video/video.c: Likewise. + +2009-12-23 Felix Zielcke + + * commands/i386/pc/drivemap.c: Remove all trailing whitespace. + * commands/lspci.c: Likewise. + * commands/probe.c: Likewise. + * commands/xnu_uuid.c: Likewise. + * conf/i386-coreboot.rmk: Likewise. + * conf/i386-efi.rmk: Likewise. + * conf/i386-ieee1275.rmk: Likewise. + * conf/i386-pc.rmk: Likewise. + * conf/powerpc-ieee1275.rmk: Likewise. + * conf/sparc64-ieee1275.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + * fs/i386/pc/pxe.c: Likewise. + * gettext/gettext.c: Likewise. + * include/grub/efi/graphics_output.h: Likewise. + * include/grub/i386/pc/memory.h: Likewise. + * kern/env.c: Likewise. + * kern/i386/qemu/startup.S: Likewise. + * lib/i386/pc/biosnum.c: Likewise. + * lib/i386/relocator.c: Likewise. + * lib/i386/relocator_asm.S: Likewise. + * lib/relocator.c: Likewise. + * loader/i386/bsd.c: Likewise. + * loader/i386/multiboot.c: Likewise. + * loader/i386/pc/chainloader.c: Likewise. + * loader/i386/xnu.c: Likewise. + * loader/xnu.c: Likewise. + * normal/main.c: Likewise. + * normal/menu_text.c: Likewise. + * util/getroot.c: Likewise. + * util/grub-mkconfig_lib.in: Likewise. + * util/grub.d/00_header.in: Likewise. + * util/i386/pc/grub-mkimage.c: Likewise. + * util/mkisofs/eltorito.c: Likewise. + * util/mkisofs/exclude.h: Likewise. + * util/mkisofs/hash.c: Likewise. + * util/mkisofs/iso9660.h: Likewise. + * util/mkisofs/joliet.c: Likewise. + * util/mkisofs/mkisofs.c: Likewise. + * util/mkisofs/mkisofs.h: Likewise. + * util/mkisofs/multi.c: Likewise. + * util/mkisofs/name.c: Likewise. + * util/mkisofs/rock.c: Likewise. + * util/mkisofs/tree.c: Likewise. + * util/mkisofs/write.c: Likewise. + * video/efi_gop.c: Likewise. + +2009-12-23 Vladimir Serbinenko + + * video/efi_gop.c (grub_video_gop_get_bitmask): Fix off-by-one in mask + size counting. + +2009-12-22 Felix Zielcke + + * util/grub-mkrescue.in (pkglib_DATA): Set to @pkglib_DATA@. + * genmk.rb (class SCRIPT): Modify the target file instead of source. + +2009-12-22 Vladimir Serbinenko + + * commands/memrw.c (grub_cmd_write): Support for mask parameter. + (GRUB_MOD_INIT(memrw)): Update help line. + +2009-12-22 Vladimir Serbinenko + + * commands/memrw.c (cmd_read_byte, cmd_read_word, cmd_read_dword): + Use grub_extcmd_t. All users updated. + (options): New variable. + (grub_cmd_read): Restructure for readability. Support "-v" option. + (grub_cmd_write): Restructure for readability. + +2009-12-22 Felix Zielcke + + * genmk.rb (class SCRIPT): Prepend #{src} path with $(srcdir). + +2009-12-22 Felix Zielcke + + * genmk.rb (class SCRIPT): Use sed to substitute @pkglib_DATA@ + with the actual contents of the correspondending make variable. + * util/grub-mkrescue.in (pkglib_DATA): New variable. + (process_input_dir): Copy all $pkglib_DATA files instead of explicitly + specifying `*.lst' and `efiemu??.o' + +2009-12-22 Felix Zielcke + + * util/grub.d/30_os-prober.in (osx_entry): Add round brackets + after function name. + Noticed by Rene Engelhard . + +2009-12-22 Vladimir Serbinenko + + * commands/lspci.c (grub_pci_classes): Add "USB Controller". + (options): New variable. + (iospace): Likewise. + (grub_lspci_iter): List IO spaces if "-i" was given. + (grub_cmd_lspci): Parse options. + (GRUB_MOD_INIT(lspci)): Use extcmd. + (GRUB_MOD_FINI(lspci)): Likewise. + +2009-12-22 Felix Zielcke + + * util/grub.d/30_os-prober.in (osx_entry): Remove non POSIX compliant + `function' keyword. + Patch by Tony Mancill . + +2009-12-22 Vladimir Serbinenko + + * bus/usb/uhci.c (grub_uhci_transfer): Set a limit transaction time. + (grub_uhci_portstatus): Likewise. + (grub_uhci_portstatus): Add necessary delay. + * bus/usb/usbhub.c (grub_usb_hub_add_dev): Fix loop-break condition. + +2009-12-21 Carles Pina i Estany + + * commands/acpi.c (options): Fix capitalizations and/or full stops. + (GRUB_MOD_INIT): Likewise. + * commands/boot.c (GRUB_MOD_INIT): Likewise. + * commands/cmp.c (grub_cmd_cmp): Improve the help message. + * commands/echo.c (options): Fix capitalizations and/or full stops. + * commands/efi/loadbios.c (enable_rom_area): Likewise. + (enable_rom_area): Likewise. + (GRUB_MOD_INIT): Likewise. + * commands/gptsync.c (GRUB_MOD_INIT): Likewise. + * commands/halt.c (GRUB_MOD_INIT): Improve the help message. + * commands/handler.c (GRUB_MOD_INIT): Likewise. + * commands/hdparm.c (options): Fix capitalizations and/or full stops. + * commands/hexdump.c (options): Likewise. + * commands/i386/cpuid.c (options): Likewise. + (GRUB_MOD_INIT): Likewise. + * commands/i386/pc/drivemap.c (options): Likewise. + (GRUB_MOD_INIT): Likewise. + * commands/i386/pc/halt (options): Likewise. + (GRUB_MOD_INIT): Likewise. + * commands/i386/pc/play.c (GRUB_MOD_INIT): Likewise. + * commands/i386/pc/pxecmd.c (options): Likewise. + * commands/i386/pc/vbetest.c (GRUB_MOD_INIT): Likewise. + * commands/ieee1275/suspend.c (GRUB_MOD_INIT): Likewise. + * commands/keystatus.c (options): Likewise. + (GRUB_MOD_INIT): Likewise. + * commands/loadenv.c (options): Likewise. + * commands/ls.c (options): Likewise. + * commands/lspci.c (GRUB_MOD_INIT): Likewise. + * commands/memrw.c (GRUB_MOD_INIT): Likewise. + * commands/minicmd.c (GRUB_MOD_INIT): Likewise. + * commands/parttool.c (helpmsg): Likewise. + * commands/probe.c (options): Likewise. + * commands/read.c (GRUB_MOD_INIT): Likewise. + * commands/reboot.c (GRUB_MOD_INIT): Likewise. + * commands/search.c (options): Likewise. + * commands/sleep.c (options): Likewise. + * commands/test.c (GRUB_MOD_INIT): Likewise. + * commands/true.c (GRUB_MOD_INIT): Likewise. + * commands/usbtest.c (GRUB_MOD_INIT): Likewise. + * commands/videotest.c (GRUB_MOD_INIT): Likewise. + * lib/arg.c (help_options): Likewise. + * Makefile.in ($(srcdir)/po/$(PACKAGE).pot): Pass -ctranslate to + `$(XGETTEXT)'. + * po/POTFILES: Add `commands/loadenv.c'. + +2009-12-21 Felix Zielcke + + * util/grub-mkrescue.in (process_input_dir): Copy `*.lst' files + instead of specifying them explicit. + +2009-12-21 Robert Millan + + * NEWS: Add grub-probe support for GNU/Hurd. + +2009-12-21 Robert Millan + + * NEWS: gettext was added after 1.97. + +2009-12-21 Robert Millan + + * util/mkisofs/msdos_partition.h: New file (based on + include/grub/msdos_partition.h). + * util/mkisofs/mkisofs.c (use_protective_msdos_label): New variable. + (OPTION_PROTECTIVE_MSDOS_LABEL): New macro. + (ld_options, main): Recognize --protective-msdos-label. + * util/mkisofs/mkisofs.h (use_protective_msdos_label): New declaration. + * util/mkisofs/write.c: Include `"msdos_partition.h"'. + (padblock_write): If `use_protective_msdos_label' is set, patch a + protective DOS-style label in the output image. + + * util/grub-mkrescue.in: Use --protective-msdos-label. + +2009-12-21 Robert Millan + + * util/grub-mkrescue.in: Do not zero-pad image for BIOS-based disk + boot. + +2009-12-21 Robert Millan + + * util/mkisofs/mkisofs.c (use_embedded_boot, boot_image_embed): New + variables. + (ld_options, main): Recognize `--embedded-boot'. + * util/mkisofs/mkisofs.h (use_embedded_boot, boot_image_embed): New + declarations. + * util/mkisofs/write.c (PADBLOCK_SIZE): New variable. + (padblock_size): Use `PADBLOCK_SIZE' instead of hardcoding 16. + (padblock_write): Likewise. Rewrite to support embedded boot image. + + * util/grub-mkrescue.in: When building i386-pc images, embed core.img + for BIOS-based disk boot instead of only ElTorito. + +2009-12-21 Robert Millan + + * util/grub-mkrescue.in: Remove `configfile' and `sh' from i386-pc + build (not needed for bootstrap). + +2009-12-21 Robert Millan + + * util/grub-mkrescue.in: Remove `memdisk', `tar' and `search' modules + from i386-pc build (not needed for bootstrap). + Rewrite a pair of strings. + +2009-12-21 Robert Millan + + * normal/main.c (grub_normal_reader_init): Set left margin back to 3. + +2009-12-21 Vladimir Serbinenko + + * video/i386/pc/vbe.c (grub_video_vbe_fini): Set 'last_set_mode'. + +2009-12-21 Andreas Born + + * kern/env.c (grub_env_context_open): Mark exported variable for + reexport. + +2009-12-21 Andreas Born + + * kern/env.c (grub_env_export): Create nonexistent variables before + exporting. + +2009-12-20 Carles Pina i Estany + + * include/grub/auth.h: Include `'. + (GRUB_GET_PASSWORD): Gettextizze string. + * include/grub/normal.h (STANDARD_MARGIN): New macro, moved from + menu_text.c. + (grub_utf8_to_ucs4_alloc): Fix indentation. + (grub_print_ucs4): Likewise. + (grub_getstringwidth): Likewise. + (print_message_indented): New declaration. + * normal/auth.c: Include `'. + (grub_auth_check_authentication): Gettexttize string. + * normal/cmdline.c: Include `'. + (grub_cmdline_get): Gettextizze. + * normal/color.c: Include `'. + (grub_parse_color_name_pair): Gettexttize strings. + * normal/main.c (grub_normal_reader_init): Cleanup gettexttized + string (use `print_message_indented'). + * normal/menu_text.c (STANDARD_MARGIN): Moved from here to + `include/grub/normal.h'. + (print_message_indented): Renamed to ... + (grub_print_message_indented): ... this. Remove `static' qualifer (now + used in normal/main.c). + (print_message): Use `grub_print_message_indented' instead of + `print_message_indented'. + (print_timeout): Likewise. + * normal/misc.c: Include `' and `'. + (grub_normal_print_device_info): Gettexttize strings. + * po/POTFILES: Add `auth.c', `color.c' and `misc.c'. + +2009-12-20 Vladimir Serbinenko + + * kern/parser.c (grub_parser_split_cmdline): Fix incorrect counting + of arguments. Return number of tokens and not arguments. All users + updated. + +2009-12-20 Vladimir Serbinenko + + * util/i386/pc/grub-setup.c (setup): Don't install on non-GPT, + non-MSDOS paritions. + +2009-12-19 Vladimir Serbinenko + + * include/grub/types.h (UNUSED): Removed since it conflicts with + NetBSD headers. All users changed to direct __attribute__ ((unused)). + Reported by GrĂ©goire Sutre. + +2009-12-19 Carles Pina i Estany + + * include/grub/normal.h (grub_utf8_to_ucs4): New declaration. + (grub_print_ucs4_alloc): Likewise. + (grub_getstringwidth): Likewise. + * normal/main.c (grub_normal_init_page): Gettextize version string. + * normal/menu_text.c (grub_utf8_to_ucs4_alloc): New definition. + (getstringwidth): Renamed to ... + (grub_getstringwidth): ... this. Remove `static' qualifier (now used + in normal/main.c). Use `grub_utf8_to_ucs4_alloc'. + (grub_print_ucs4): Remove `static' qualifer (now used in + normal/main.c). + * po/POTFILES: Add normal/main.c. + +2009-12-19 Carles Pina i Estany + + * normal/menu_text.c (STANDARD_MARGIN): New macro. + (print_message_indented): Add `margin_left' and `margin_right' + parameters. + (print_message): Update `print_message_indented' calls. Adds '\n' to the + strings. + (print_timeout): Use `print_message_indented' to print the message. + Deletes `second_stage' parameter. + (run_menu): Update `print_timeout' calls. + +2009-12-18 Vladimir Serbinenko + + Fix console palette on OpenFirmware. + + * term/ieee1275/ofconsole.c (MAX): Removed. + (colors): Redone based on VGA palette. + (grub_ofconsole_setcolor): Discard brightness bit since only 8 + colors are supported. + (grub_ofconsole_init_output): Use ARRAY_SIZE instead of hardcoded size. + +2009-12-18 Vladimir Serbinenko + + Fix potential EfiEmu double prepare. + + * efiemu/main.c (prepared): New variable + (grub_efiemu_unload): Set prepare to '0'. + (grub_efiemu_prepare): Return if already prepared. Set prepared. + + set_virtual_address_map support. + + * include/grub/efi/efi.h (grub_efi_set_virtual_address_map): New + prototype. + * include/grub/efiemu/efiemu.h (grub_efiemu_write_sym_markers): New + prototype. + (grub_efiemu_crc32): Likewise. + (grub_efiemu_crc64): Likewise. + (grub_efiemu_set_virtual_address_map): Likewise. + * include/grub/autoefi.h (grub_autoefi_exit_boot_services): + New definition. + (grub_autoefi_set_virtual_address_map): Likewise. + * kern/efi/efi.c (grub_efi_set_virtual_address_map): New function. + * loader/i386/xnu.c (grub_xnu_boot): Call set_virtual_address_map. + Restructure flow to accomodate it. + * efiemu/prepare.c (grub_efiemu_prepare): Support set_virtual_address_map. + (grub_efiemu_crc): Recompute CRC32. + * efiemu/runtime/efiemu.c (ptv_relocated): Renamed to ... + (efiemu_ptv_relocated): ... this. Made global. All users updated. + * efiemu/symbols.c (relocated_handle): New variable. + (grub_efiemu_free_syms): Free relocated_handle. + (grub_efiemu_alloc_syms): Allocate relocated_handle. + (grub_efiemu_write_sym_markers): New function. + (grub_efiemu_set_virtual_address_map): Likewise. + + Newer XNU parameters. + + * include/grub/i386/xnu.h (GRUB_XNU_BOOTARGS_VERMINOR): Change to 5. + * include/grub/xnu.h (grub_xnu_extheader): Add nameaddr and namesize. + (grub_xnu_fill_devicetree): New prototype. + (grub_xnu_heap_real_start): New variable. + * loader/xnu.c (get_name_ptr): New function. + (grub_xnu_load_driver): Fill namelen and name. + + 64-bit xnu support. + + * conf/i386-efi.rmk (xnu_mod_SOURCES): Add 'loader/macho32.c' + and 'loader/macho64.c'. + * conf/i386-pc.rmk: Likewise. + * conf/x86_64-efi.rmk: Likewise. + * include/grub/i386/macho.h (grub_macho_thread64): New structure. + * include/grub/xnu.h (grub_xnu_is_64bit): New variable. + * include/grub/macho.h (grub_macho_segment64): New structure. + * include/grub/machoload.h (grub_macho32_size): Renamed from ... + (grub_macho_size32): ... to this. + (grub_macho32_get_entry_point): Renamed from ... + (grub_macho_get_entry_point32): ... to this. + (grub_macho_contains_macho64): New prototype. + (grub_macho_size64): Likewise. + (grub_macho_get_entry_point64): Likewise. + (grub_macho32_load): Renamed from ... + (grub_macho_load32): ... to this. + (grub_macho32_filesize): Renamed from ... + (grub_macho_filesize32): ... to this. + (grub_macho32_readfile): Renamed from ... + (grub_macho_readfile32): ... to this. + (grub_macho_filesize64): New prototype. + (grub_macho_readfile64): Likewise. + (grub_macho_parse32): Likewise. + (grub_macho_parse64): Likewise. + * loader/macho.c: Split into ... + * loader/machoXX.c: ... and this. Replace 32 with XX. + * loader/macho32.c: New file. + * loader/macho64.c: Likewise. + * loader/xnu.c (grub_xnu_is_64bit): New variable. + (grub_cmd_xnu_kernel): Make 32-bit only. + (grub_cmd_xnu_kernel64): New function. + (grub_xnu_load_driver): Support Mach-O 64. + (grub_cmd_xnu_mkext): Likewise. + * util/grub.d/30_os-prober.in (osx_entry): New function. + Generate entries for 64-bit boot too. + + Eliminate ad-hoc tree format in XNU and EfiEmu. + + * efiemu/main.c (grub_efiemu_prepare): Update comment. + * efiemu/pnvram.c: Rewritten to use environment variables. + All users updated. + + Inline utf16_to_utf8. + + * kern/misc.c (grub_utf16_to_utf8): Move from here ... + * include/grub/charset.h (grub_utf16_to_utf8): ... to here. Inlined. + All users updated. + * include/grub/misc.h (grub_utf16_to_utf8): Removed. + + * bus/usb/usb.c (grub_usb_get_string): Move from here ... + * commands/usbtest.c (grub_usb_get_string): ... move here. + (usb_print_str): Fix error handling. + * include/grub/usb.h (grub_usb_get_string): Remove. + + UTF-8 to UTF-16 transformation. + + * conf/common.rmk (pkglib_MODULES): Add charset.mod + (charset_mod_SOURCES): New variable. + (charset_mod_CFLAGS): Likewise. + (charset_mod_LDFLAGS): Likewise. + * include/grub/utf.h: New file. + * lib/utf.c: New file. (Based on grub_utf8_to_ucs4 from kern/misc.c) + + Support for device properties. + + * include/grub/i386/xnu.h (grub_xnu_devprop_header): New structure. + (grub_xnu_devprop_device_header): Likewise. + (grub_xnu_devprop_device_descriptor): Likewise. + (grub_xnu_devprop_add_device): New prototype. + (grub_xnu_devprop_remove_device): Likewise. + (grub_xnu_devprop_remove_property): Likewise. + (grub_xnu_devprop_add_property_utf8): Likewise. + (grub_xnu_devprop_add_property_utf16): Likewise. + (grub_cpu_xnu_init): Likewise. + (grub_cpu_xnu_fini): Likewise. + (grub_cpu_xnu_unload): Likewise. + * loader/i386/xnu.c (grub_xnu_devprop_device_descriptor): New structure. + (property_descriptor): Likewise. + (devices): New variable. + (grub_xnu_devprop_remove_property): New function. + (grub_xnu_devprop_add_device): Likewise. + (grub_xnu_devprop_remove_device): Likewise. + (grub_xnu_devprop_add_property): Likewise. + (grub_xnu_devprop_add_property_utf8): Likewise. + (grub_xnu_devprop_add_property_utf16): Likewise. + (hextoval): Likewise. + (grub_cpu_xnu_fill_devprop): Likewise. + (grub_cmd_devprop_load): Likewise. + (grub_xnu_boot): Call grub_cpu_xnu_fill_devprop, + grub_xnu_fill_devicetree, grub_xnu_fill_devicetree + (cmd_devprop_load): New variable. + (grub_cpu_xnu_init): New function. + (grub_cpu_xnu_fini): Likewise. + * loader/i386/xnu.c (grub_xnu_unload): Call grub_cpu_xnu_unload. + * loader/xnu.c (grub_xnu_parse_devtree): Remove. + (grub_cmd_xnu_devtree): Likewise. + (hextoval): New function. + (unescape): Likewise. + (grub_xnu_fill_devicetree): Likewise. + + * util/grub.d/30_os-prober.in: Load devprop.bin. Don't load devtree.txt. + * util/i386/efi/grub-dumpdevtree: Generate devprop.bin. + +2009-12-18 Vladimir Serbinenko + + Workaround for broken ATI VBE. + + * video/i386/pc/vbe.c (last_set_mode): New variable. + (grub_vbe_set_video_mode): Set 'last_set_mode'. + (grub_vbe_get_video_mode): Use 'last_set_mode' if get_mode fails. + (grub_video_vbe_setup): Don't check for reserved flag. + +2009-12-17 Felix Zielcke + + * gendistlist.sh: Use POSIX compliant `!' instead of `-not' in + the `find' command. + +2009-12-16 Vladimir Serbinenko + + UUID support for HFS. + + * fs/hfs.c (grub_hfs_uuid): New function. + (grub_hfs_fs): New value .uuid. + * include/grub/hfs.h (grub_hfs_sblock): New field 'num_serial'. + +2009-12-14 Felix Zielcke + + Fix a segfault with parsing unknown long options. + + * util/grub-mkrelpath.c (options): Zero terminate it. + +2009-12-13 Carles Pina i Estany + + * include/grub/misc.h (grub_puts): New declaration. + (grub_puts_): Likewise. + * kern/misc.c (grub_puts): New definition. + (grub_puts_): Likewise. + +2009-12-13 Robert Millan + + * util/grub-probe.c (probe): Improve error message. + 2009-12-13 Robert Millan * loader/i386/multiboot_elfxx.c @@ -130,11 +866,11 @@ * include/grub/pciutils.h: New file. * util/pci.c: Likewise. -2009-12-11 Felix Zielcke +2009-12-11 Felix Zielcke * util/misc.c: Don't include twice. -2009-12-10 Felix Zielcke +2009-12-10 Felix Zielcke * disk/i386/pc/biosdisk.c (grub_biosdisk_open): Show the disk name in an error message. @@ -230,7 +966,7 @@ * disk/ieee1275/ofdisk.c (grub_ofdisk_iterate): Recognize anything even prefixed with 'cdrom' as a cdrom. -2009-12-06 Felix Zielcke +2009-12-06 Felix Zielcke * util/misc.c (make_system_path_relative_to_its_root): Correctly cope with mount points. @@ -241,7 +977,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. @@ -282,7 +1018,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. @@ -446,7 +1182,7 @@ ($(foreach lang, $(LINGUAS), $(srcdir)/po/$(lang).po)): Rewrite as ... (po/%.po): ... this. -2009-11-26 Felix Zielcke +2009-11-26 Felix Zielcke * util/i386/efi/grub-mkimage.c: Include "progname.h". (main): Use `program_name' instead of nonexistent `progname'. @@ -553,7 +1289,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/boot/i386/pc/lnxboot.S b/boot/i386/pc/lnxboot.S index c51741d42..43d170c6e 100644 --- a/boot/i386/pc/lnxboot.S +++ b/boot/i386/pc/lnxboot.S @@ -185,7 +185,7 @@ real_code_2: call LOCAL(move_memory) /* Check for multiboot signature. */ - cmpl $MULTIBOOT_MAGIC, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_DATA_END) + cmpl $MULTIBOOT_HEADER_MAGIC, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_DATA_END) jz 1f movl (ramdisk_image - start), %esi 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..523abf93e 100644 --- a/bus/usb/usbhub.c +++ b/bus/usb/usbhub.c @@ -48,9 +48,9 @@ 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"); + 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..6bf9f696b 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} }; @@ -277,7 +277,7 @@ grub_acpi_create_ebda (void) { grub_mmap_unregister (mmapregion); return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "Couldn't find suitable spot in EBDA"); + "couldn't find suitable spot in EBDA"); } /* Remove any other RSDT. */ @@ -551,7 +551,7 @@ grub_cmd_acpi (struct grub_extcmd *cmd, grub_free (exclude); grub_free (load_only); return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "Couldn't allocate table"); + "couldn't allocate table"); } grub_memcpy (table_dsdt, dsdt, dsdt->length); } @@ -578,7 +578,7 @@ grub_cmd_acpi (struct grub_extcmd *cmd, grub_free (exclude); grub_free (load_only); return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "Couldn't allocate table structure"); + "couldn't allocate table structure"); } table->size = curtable->length; table->addr = grub_malloc (table->size); @@ -587,7 +587,7 @@ grub_cmd_acpi (struct grub_extcmd *cmd, { free_tables (); return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "Couldn't allocate table"); + "couldn't allocate table"); } table->next = acpi_tables; acpi_tables = table; @@ -674,7 +674,7 @@ grub_cmd_acpi (struct grub_extcmd *cmd, { free_tables (); return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "Couldn't allocate table structure"); + "couldn't allocate table structure"); } table->size = size; @@ -709,7 +709,7 @@ grub_cmd_acpi (struct grub_extcmd *cmd, { free_tables (); return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "Couldn't allocate space for ACPI tables"); + "couldn't allocate space for ACPI tables"); } setup_common_tables (); @@ -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/blocklist.c b/commands/blocklist.c index b457b7c39..51a91e2d7 100644 --- a/commands/blocklist.c +++ b/commands/blocklist.c @@ -87,7 +87,7 @@ grub_cmd_blocklist (grub_command_t cmd __attribute__ ((unused)), if (! file->device->disk) return grub_error (GRUB_ERR_BAD_DEVICE, - "this command is available only for disk devices."); + "this command is available only for disk devices"); if (file->device->disk->partition) part_start = grub_partition_get_start (file->device->disk->partition); 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..877b5da17 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; } @@ -160,7 +160,7 @@ grub_cmd_loadbios (grub_command_t cmd __attribute__ ((unused)), int size; if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "No rom image specified"); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no ROM image specified"); if (argc > 1) { @@ -169,7 +169,7 @@ grub_cmd_loadbios (grub_command_t cmd __attribute__ ((unused)), return grub_errno; if (file->size != 4) - grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid int10 dump size"); + grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid int10 dump size"); else grub_file_read (file, (void *) 0x40, 4); @@ -184,7 +184,7 @@ grub_cmd_loadbios (grub_command_t cmd __attribute__ ((unused)), size = file->size; if ((size < 0x10000) || (size > 0x40000)) - grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid bios dump size"); + grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid bios dump size"); else if (enable_rom_area ()) { grub_file_read (file, (void *) VBIOS_ADDR, size); @@ -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/help.c b/commands/help.c index c18ec6b83..c24540cef 100644 --- a/commands/help.c +++ b/commands/help.c @@ -21,6 +21,7 @@ #include #include #include +#include static grub_err_t grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc, @@ -38,13 +39,14 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc, (cmd->flags & GRUB_COMMAND_FLAG_CMDLINE)) { char description[GRUB_TERM_WIDTH / 2]; - int desclen = grub_strlen (cmd->summary); + const char* summary_translated = _(cmd->summary); + int desclen = grub_strlen (summary_translated); /* Make a string with a length of GRUB_TERM_WIDTH / 2 - 1 filled with the description followed by spaces. */ grub_memset (description, ' ', GRUB_TERM_WIDTH / 2 - 1); description[GRUB_TERM_WIDTH / 2 - 1] = '\0'; - grub_memcpy (description, cmd->summary, + grub_memcpy (description, summary_translated, (desclen < GRUB_TERM_WIDTH / 2 - 1 ? desclen : GRUB_TERM_WIDTH / 2 - 1)); @@ -65,8 +67,8 @@ grub_cmd_help (grub_extcmd_t ext __attribute__ ((unused)), int argc, if (cmd->flags & GRUB_COMMAND_FLAG_EXTCMD) grub_arg_show_help ((grub_extcmd_t) cmd->data); else - grub_printf ("Usage: %s\n%s\b", cmd->summary, - cmd->description); + grub_printf ("%s %s\n%s\b", _("Usage:"), _(cmd->summary), + _(cmd->description)); } } return 0; @@ -94,8 +96,8 @@ GRUB_MOD_INIT(help) { cmd = grub_register_extcmd ("help", grub_cmd_help, GRUB_COMMAND_FLAG_CMDLINE, - "help [PATTERN ...]", - "Show a help message.", 0); + N_("help [PATTERN ...]"), + N_("Show a help message."), 0); } GRUB_MOD_FINI(help) 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..adef57576 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} }; @@ -308,7 +308,7 @@ install_int13_handler (int noret __attribute__ ((unused))) GRUB_MACHINE_MEMORY_RESERVED, GRUB_MMAP_MALLOC_LOW); if (! handler_base) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Could not reserve " + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't reserve " "memory for the int13h handler"); /* Copy int13h handler bundle to reserved area. */ @@ -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..86c0674a4 100644 --- a/commands/i386/pc/play.c +++ b/commands/i386/pc/play.c @@ -27,6 +27,7 @@ #include #include #include +#include #define BASE_TEMPO 120 @@ -207,7 +208,7 @@ static grub_command_t cmd; GRUB_MOD_INIT(play) { cmd = grub_register_command ("play", grub_cmd_play, - "play FILE", "Play a tune"); + N_("play FILE"), N_("Play a tune.")); } GRUB_MOD_FINI(play) diff --git a/commands/i386/pc/pxecmd.c b/commands/i386/pc/pxecmd.c index df538704c..b2c99c4e2 100644 --- a/commands/i386/pc/pxecmd.c +++ b/commands/i386/pc/pxecmd.c @@ -1,7 +1,7 @@ /* pxe.c - command to control the pxe driver */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008 Free Software Foundation, Inc. + * Copyright (C) 2008,2009 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,79 +21,31 @@ #include #include #include -#include - -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}, - {0, 0, 0, 0, 0, 0} - }; - -static void -print_ip (grub_uint32_t ip) -{ - int i; - - for (i = 0; i < 3; i++) - { - grub_printf ("%d.", ip & 0xFF); - ip >>= 8; - } - grub_printf ("%d", ip); -} +#include static grub_err_t -grub_cmd_pxe (grub_extcmd_t cmd, int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) +grub_cmd_pxe_unload (grub_command_t cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) { - struct grub_arg_list *state = cmd->state; - if (! grub_pxe_pxenv) return grub_error (GRUB_ERR_FILE_NOT_FOUND, "no pxe environment"); - if (state[1].set) - { - int size; - - size = grub_strtoul (state[1].arg, 0, 0); - if (size < GRUB_PXE_MIN_BLKSIZE) - size = GRUB_PXE_MIN_BLKSIZE; - else if (size > GRUB_PXE_MAX_BLKSIZE) - size = GRUB_PXE_MAX_BLKSIZE; - - grub_pxe_blksize = size; - } - - if (state[0].set) - { - grub_printf ("blksize : %d\n", grub_pxe_blksize); - grub_printf ("client ip : "); - print_ip (grub_pxe_your_ip); - grub_printf ("\nserver ip : "); - print_ip (grub_pxe_server_ip); - grub_printf ("\ngateway ip : "); - print_ip (grub_pxe_gateway_ip); - grub_printf ("\n"); - } - - if (state[2].set) - grub_pxe_unload (); + grub_pxe_unload (); return 0; } -static grub_extcmd_t cmd; +static grub_command_t cmd; GRUB_MOD_INIT(pxecmd) { - cmd = grub_register_extcmd ("pxe", grub_cmd_pxe, GRUB_COMMAND_FLAG_BOTH, - "pxe [-i|-b|-u]", - "Command to control the PXE device.", options); + cmd = grub_register_command ("pxe_unload", grub_cmd_pxe_unload, + "pxe_unload", + "Unload PXE environment."); } GRUB_MOD_FINI(pxecmd) { - grub_unregister_extcmd (cmd); + grub_unregister_command (cmd); } 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..ac5064df9 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} }; @@ -328,7 +328,7 @@ grub_cmd_save_env (grub_extcmd_t cmd, int argc, char **args) } if (! argc) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "No variable is specified"); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no variable is specified"); file = open_envblk_file ((state[0].set) ? state[0].arg : 0); if (! file) 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..de3ac38e1 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"); + 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) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid number of arguments"); + 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/password.c b/commands/password.c index 0e048797e..710283b3d 100644 --- a/commands/password.c +++ b/commands/password.c @@ -53,7 +53,7 @@ grub_cmd_password (grub_command_t cmd __attribute__ ((unused)), char *pass; if (argc != 2) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Two arguments expected."); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "two arguments expected"); pass = grub_strdup (args[1]); if (!pass) 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..b89295921 100644 --- a/commands/search.c +++ b/commands/search.c @@ -26,14 +26,15 @@ #include #include #include +#include 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, N_("Search devices by a file."), 0, 0}, + {"label", 'l', 0, N_("Search devices by a filesystem label."), 0, 0}, + {"fs-uuid", 'u', 0, N_("Search devices by a filesystem UUID."), 0, 0}, + {"set", 's', GRUB_ARG_OPTION_OPTIONAL, N_("Set a variable to the first device found."), "VAR", ARG_TYPE_STRING}, + {"no-floppy", 'n', 0, N_("Do not probe any floppy drive."), 0, 0}, {0, 0, 0, 0, 0, 0} }; @@ -186,11 +187,11 @@ GRUB_MOD_INIT(search) cmd = grub_register_extcmd ("search", grub_cmd_search, GRUB_COMMAND_FLAG_BOTH, - "search [-f|-l|-u|-s|-n] NAME", - "Search devices by file, filesystem label or filesystem UUID." + N_("search [-f|-l|-u|-s|-n] NAME"), + N_("Search devices by file, filesystem label or filesystem UUID." " If --set is specified, the first device found is" " set to a variable. If no variable name is" - " specified, \"root\" is used.", + " specified, \"root\" is used."), options); } 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..e27552510 100644 --- a/commands/videotest.c +++ b/commands/videotest.c @@ -71,7 +71,7 @@ grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)), sanssmall = grub_font_get ("Helvetica 8"); fixed = grub_font_get ("Fixed 20"); if (! sansbig || ! sans || ! sanssmall || ! fixed) - return grub_error (GRUB_ERR_BAD_FONT, "No font loaded."); + return grub_error (GRUB_ERR_BAD_FONT, "no font loaded"); glyph = grub_font_get_glyph (fixed, '*'); grub_font_draw_glyph (glyph, color, 200 ,0); @@ -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 794e9a993..671f98e62 100644 --- a/conf/i386-coreboot.rmk +++ b/conf/i386-coreboot.rmk @@ -111,7 +111,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 5481cf1f7..4f105460e 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 baba84939..3d2454d98 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/disk/ata.c b/disk/ata.c index 9761f65fb..cdd4603b0 100644 --- a/disk/ata.c +++ b/disk/ata.c @@ -281,7 +281,7 @@ grub_ata_identify (struct grub_ata_device *dev) else /* Other Error. */ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, - "device can not be identified"); + "device cannot be identified"); } grub_ata_pio_read (dev, info, GRUB_DISK_SECTOR_SIZE); @@ -534,7 +534,7 @@ grub_ata_setaddress (struct grub_ata_device *dev, || cylinder > dev->cylinders || head > dev->heads) return grub_error (GRUB_ERR_OUT_OF_RANGE, - "sector %d can not be addressed " + "sector %d cannot be addressed " "using CHS addressing", sector); grub_ata_regset (dev, GRUB_ATA_REG_DISK, (dev->device << 4) | head); @@ -689,7 +689,7 @@ grub_ata_open (const char *name, grub_disk_t disk) } if (! dev) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device"); + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); if (dev->atapi) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not an ATA harddisk"); @@ -789,7 +789,7 @@ grub_atapi_read (struct grub_scsi *scsi, /* Count of last transfer may be uneven. */ if (! (0 < cnt && cnt <= size - nread && (! (cnt & 1) || cnt == size - nread))) - return grub_error (GRUB_ERR_READ_ERROR, "Invalid ATAPI transfer count"); + return grub_error (GRUB_ERR_READ_ERROR, "invalid ATAPI transfer count"); /* Read the data. */ grub_ata_pio_read (dev, buf + nread, cnt); @@ -835,7 +835,7 @@ grub_atapi_open (const char *name, struct grub_scsi *scsi) grub_dprintf ("ata", "opening ATAPI dev `%s'\n", name); if (! devfnd) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such ATAPI device"); + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such ATAPI device"); scsi->data = devfnd; diff --git a/disk/ata_pthru.c b/disk/ata_pthru.c index 70d4f3a78..f52725a49 100644 --- a/disk/ata_pthru.c +++ b/disk/ata_pthru.c @@ -30,7 +30,7 @@ grub_ata_pass_through (grub_disk_t disk, { if (disk->dev->id != GRUB_DISK_DEVICE_ATA_ID) return grub_error (GRUB_ERR_BAD_DEVICE, - "Device not accessed via ata.mod"); + "device not accessed via ata.mod"); struct grub_ata_device *dev = (struct grub_ata_device *) disk->data; diff --git a/disk/dmraid_nvidia.c b/disk/dmraid_nvidia.c index 84dfad8c4..46eac6ac5 100644 --- a/disk/dmraid_nvidia.c +++ b/disk/dmraid_nvidia.c @@ -107,7 +107,7 @@ grub_dmraid_nv_detect (grub_disk_t disk, struct grub_raid_array *array) if (sb.version != NV_VERSION) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "Unknown version: %d.%d", sb.version); + "unknown version: %d.%d", sb.version); switch (sb.array.raid_level) { @@ -129,7 +129,7 @@ grub_dmraid_nv_detect (grub_disk_t disk, struct grub_raid_array *array) default: return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "Unsupported RAID level: %d", sb.array.raid_level); + "unsupported RAID level: %d", sb.array.raid_level); } array->number = 0; diff --git a/disk/ieee1275/nand.c b/disk/ieee1275/nand.c index 37427f884..a9ed553cf 100644 --- a/disk/ieee1275/nand.c +++ b/disk/ieee1275/nand.c @@ -67,7 +67,7 @@ grub_nand_open (const char *name, grub_disk_t disk) } args; if (! grub_strstr (name, "nand")) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Not a nand device"); + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a NAND device"); data = grub_malloc (sizeof (*data)); if (! data) @@ -76,7 +76,7 @@ grub_nand_open (const char *name, grub_disk_t disk) grub_ieee1275_open (name, &dev_ihandle); if (! dev_ihandle) { - grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device"); + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); goto fail; } @@ -89,7 +89,7 @@ grub_nand_open (const char *name, grub_disk_t disk) if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.result)) { - grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't get block size"); + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't get block size"); goto fail; } @@ -102,7 +102,7 @@ grub_nand_open (const char *name, grub_disk_t disk) if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.result)) { - grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't get disk size"); + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't get disk size"); goto fail; } @@ -172,7 +172,7 @@ grub_nand_read (grub_disk_t disk, grub_disk_addr_t sector, args.result = 1; if ((IEEE1275_CALL_ENTRY_FN (&args) == -1) || (args.result)) - return grub_error (GRUB_ERR_READ_ERROR, "Read error"); + return grub_error (GRUB_ERR_READ_ERROR, "read error"); ofs = 0; size -= len; diff --git a/disk/ieee1275/ofdisk.c b/disk/ieee1275/ofdisk.c index a33d729e3..c2a3a2c3a 100644 --- a/disk/ieee1275/ofdisk.c +++ b/disk/ieee1275/ofdisk.c @@ -175,7 +175,7 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) grub_ieee1275_open (op->devpath, &dev_ihandle); if (! dev_ihandle) { - grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device"); + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); goto fail; } @@ -184,20 +184,20 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) if (grub_ieee1275_finddevice (op->devpath, &dev)) { - grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't read device properties"); + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't read device properties"); goto fail; } if (grub_ieee1275_get_property (dev, "device_type", prop, sizeof (prop), &actual)) { - grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't read the device type"); + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't read the device type"); goto fail; } if (grub_strcmp (prop, "block")) { - grub_error (GRUB_ERR_BAD_DEVICE, "Not a block device"); + grub_error (GRUB_ERR_BAD_DEVICE, "not a block device"); goto fail; } @@ -244,12 +244,12 @@ grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector, (int) (pos >> 32), (int) pos & 0xFFFFFFFFUL, &status); if (status < 0) return grub_error (GRUB_ERR_READ_ERROR, - "Seek error, can't seek block %llu", + "seek error, can't seek block %llu", (long long) sector); grub_ieee1275_read ((grub_ieee1275_ihandle_t) (unsigned long) disk->data, buf, size * 512UL, &actual); if (actual != actual) - return grub_error (GRUB_ERR_READ_ERROR, "Read error on block: %llu", + return grub_error (GRUB_ERR_READ_ERROR, "read error on block: %llu", (long long) sector); return 0; diff --git a/disk/loopback.c b/disk/loopback.c index 29805182e..c877dd8af 100644 --- a/disk/loopback.c +++ b/disk/loopback.c @@ -56,7 +56,7 @@ delete_loopback (const char *name) break; if (! dev) - return grub_error (GRUB_ERR_BAD_DEVICE, "Device not found"); + return grub_error (GRUB_ERR_BAD_DEVICE, "device not found"); /* Remove the device from the list. */ *prev = dev->next; @@ -167,7 +167,7 @@ grub_loopback_open (const char *name, grub_disk_t disk) break; if (! dev) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device"); + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); file = grub_file_open (dev->filename); if (! file) diff --git a/disk/lvm.c b/disk/lvm.c index 126b49439..8d0c75a6d 100644 --- a/disk/lvm.c +++ b/disk/lvm.c @@ -95,7 +95,7 @@ grub_lvm_open (const char *name, grub_disk_t disk) } if (! lv) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Unknown LVM device %s", name); + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown LVM device %s", name); disk->has_partitions = 0; disk->id = lv->number; @@ -188,7 +188,7 @@ grub_lvm_read (grub_disk_t disk, grub_disk_addr_t sector, size << GRUB_DISK_SECTOR_BITS, buf); else err = grub_error (GRUB_ERR_UNKNOWN_DEVICE, - "Physical volume %s not found", pv->name); + "physical volume %s not found", pv->name); return err; } @@ -263,7 +263,7 @@ grub_lvm_scan_device (const char *name) if (dlocn->offset) { grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "We don't support multiple LVM data areas"); + "we don't support multiple LVM data areas"); goto fail; } @@ -290,7 +290,7 @@ grub_lvm_scan_device (const char *name) || (grub_le_to_cpu32 (mdah->version) != GRUB_LVM_FMTT_VERSION)) { grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "Unknown LVM metadata header"); + "unknown LVM metadata header"); goto fail2; } diff --git a/disk/mdraid_linux.c b/disk/mdraid_linux.c index 29a21b4c7..306c66a8b 100644 --- a/disk/mdraid_linux.c +++ b/disk/mdraid_linux.c @@ -181,7 +181,7 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array) /* FIXME: Also support version 1.0. */ if (sb.major_version != 0 || sb.minor_version != 90) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "Unsupported RAID version: %d.%d", + "unsupported RAID version: %d.%d", sb.major_version, sb.minor_version); /* FIXME: Check the checksum. */ @@ -193,7 +193,7 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array) if (sb.level != 0 && sb.level != 1 && sb.level != 4 && sb.level != 5 && sb.level != 6 && sb.level != 10) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "Unsupported RAID level: %d", sb.level); + "unsupported RAID level: %d", sb.level); array->number = sb.md_minor; array->level = sb.level; diff --git a/disk/raid.c b/disk/raid.c index c720fb36c..c48a41d8d 100644 --- a/disk/raid.c +++ b/disk/raid.c @@ -123,7 +123,7 @@ grub_raid_open (const char *name, grub_disk_t disk) } if (!array) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Unknown RAID device %s", + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "unknown RAID device %s", name); disk->has_partitions = 1; @@ -265,7 +265,7 @@ grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector, } else err = grub_error (GRUB_ERR_READ_ERROR, - "disk missing."); + "disk missing"); k++; if (k == array->total_devs) diff --git a/disk/raid6_recover.c b/disk/raid6_recover.c index 7bbf8eaef..ed0e92523 100644 --- a/disk/raid6_recover.c +++ b/disk/raid6_recover.c @@ -157,7 +157,7 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, if (! array->device[q]) { - grub_error (GRUB_ERR_READ_ERROR, "Not enough disk to restore"); + grub_error (GRUB_ERR_READ_ERROR, "not enough disk to restore"); goto quit; } @@ -176,7 +176,7 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p, if ((! array->device[p]) || (! array->device[q])) { - grub_error (GRUB_ERR_READ_ERROR, "Not enough disk to restore"); + grub_error (GRUB_ERR_READ_ERROR, "not enough disk to restore"); goto quit; } diff --git a/disk/scsi.c b/disk/scsi.c index d0e248511..21b888559 100644 --- a/disk/scsi.c +++ b/disk/scsi.c @@ -337,14 +337,14 @@ grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector, unsigned spb = scsi->blocksize >> GRUB_DISK_SECTOR_BITS; if (! (spb != 0 && (scsi->blocksize & GRUB_DISK_SECTOR_SIZE) == 0)) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "Unsupported SCSI block size"); + "unsupported SCSI block size"); grub_uint32_t sector_mod = 0; sector = grub_divmod64 (sector, spb, §or_mod); if (! (sector_mod == 0 && size % spb == 0)) return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "Unaligned SCSI read not supported"); + "unaligned SCSI read not supported"); size /= spb; } diff --git a/efiemu/main.c b/efiemu/main.c index b5608e666..f6d7b2e4c 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; } @@ -211,7 +214,7 @@ grub_efiemu_load_file (const char *filename) { grub_file_close (file); grub_efiemu_unload (); - return grub_error (grub_errno, "Couldn't init memory management"); + return grub_error (grub_errno, "couldn't init memory management"); } grub_dprintf ("efiemu", "mm initialized\n"); @@ -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/mm.c b/efiemu/mm.c index 8b0322942..6099a14ee 100644 --- a/efiemu/mm.c +++ b/efiemu/mm.c @@ -67,7 +67,7 @@ grub_efiemu_add_to_mmap (grub_uint64_t start, grub_uint64_t size, * sizeof (grub_efi_memory_descriptor_t)); if (!efiemu_mmap) return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "Not enough space for memory map"); + "not enough space for memory map"); } /* Fill slot*/ @@ -622,7 +622,7 @@ grub_efiemu_mm_do_alloc (void) if (!efiemu_mmap) { grub_efiemu_unload (); - return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Couldn't initialize mmap"); + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't initialize mmap"); } if ((err = efiemu_alloc_requests ())) diff --git a/efiemu/pnvram.c b/efiemu/pnvram.c index 04ad6e284..e58fce84e 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"); + 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..4fc546b59 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/font/font.c b/font/font.c index a6cdf3c93..6223366f7 100644 --- a/font/font.c +++ b/font/font.c @@ -209,7 +209,7 @@ open_section (grub_file_t file, struct font_file_section *section) else if (retval < 0) { grub_error (GRUB_ERR_BAD_FONT, - "Font format error: can't read section name"); + "font format error: can't read section name"); return 1; } @@ -224,7 +224,7 @@ open_section (grub_file_t file, struct font_file_section *section) else if (retval < 0) { grub_error (GRUB_ERR_BAD_FONT, - "Font format error: can't read section length"); + "font format error: can't read section length"); return 1; } @@ -258,7 +258,7 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct if ((sect_length % FONT_CHAR_INDEX_ENTRY_SIZE) != 0) { grub_error (GRUB_ERR_BAD_FONT, - "Font file format error: character index length %d " + "font file format error: character index length %d " "is not a multiple of the entry size %d", sect_length, FONT_CHAR_INDEX_ENTRY_SIZE); return 1; @@ -293,7 +293,7 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct if (i != 0 && entry->code <= last_code) { grub_error (GRUB_ERR_BAD_FONT, - "Font characters not in ascending order: %u <= %u", + "font characters not in ascending order: %u <= %u", entry->code, last_code); return 1; } @@ -356,7 +356,7 @@ read_section_as_short (struct font_file_section *section, grub_int16_t *value) if (section->length != 2) { grub_error (GRUB_ERR_BAD_FONT, - "Font file format error: section %c%c%c%c length " + "font file format error: section %c%c%c%c length " "is %d but should be 2", section->name[0], section->name[1], section->name[2], section->name[3], @@ -389,7 +389,7 @@ grub_font_load (grub_file_t file) if (grub_memcmp (section.name, section_names_file, 4) != 0) { grub_error (GRUB_ERR_BAD_FONT, - "Font file format error: 1st section must be FILE"); + "font file format error: 1st section must be FILE"); goto fail; } @@ -399,7 +399,7 @@ grub_font_load (grub_file_t file) if (section.length != 4) { grub_error (GRUB_ERR_BAD_FONT, - "Font file format error (file type ID length is %d " + "font file format error (file type ID length is %d " "but should be 4)", section.length); goto fail; } @@ -417,7 +417,7 @@ grub_font_load (grub_file_t file) if (grub_memcmp (magic, pff2_magic, 4) != 0) { - grub_error (GRUB_ERR_BAD_FONT, "Invalid font magic %x %x %x %x", + grub_error (GRUB_ERR_BAD_FONT, "invalid font magic %x %x %x %x", magic[0], magic[1], magic[2], magic[3]); goto fail; } @@ -544,7 +544,7 @@ grub_font_load (grub_file_t file) || font->descent == 0) { grub_error (GRUB_ERR_BAD_FONT, - "Invalid font file: missing some required data."); + "invalid font file: missing some required data"); goto fail; } diff --git a/fs/affs.c b/fs/affs.c index cfe7d579b..de20fbca1 100644 --- a/fs/affs.c +++ b/fs/affs.c @@ -182,14 +182,14 @@ grub_affs_mount (grub_disk_t disk) /* Make sure this is an affs filesystem. */ if (grub_strncmp ((char *) (data->bblock.type), "DOS", 3)) { - grub_error (GRUB_ERR_BAD_FS, "not an affs filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not an AFFS filesystem"); goto fail; } /* Test if the filesystem is a OFS filesystem. */ if (! (data->bblock.flags & GRUB_AFFS_FLAG_FFS)) { - grub_error (GRUB_ERR_BAD_FS, "ofs not yet supported"); + grub_error (GRUB_ERR_BAD_FS, "OFS not yet supported"); goto fail; } @@ -231,7 +231,7 @@ grub_affs_mount (grub_disk_t disk) } if (-checksum != checksumr) { - grub_error (GRUB_ERR_BAD_FS, "affs blocksize could not be determined"); + grub_error (GRUB_ERR_BAD_FS, "AFFS blocksize couldn't be determined"); goto fail; } blocksize++; @@ -248,7 +248,7 @@ grub_affs_mount (grub_disk_t disk) fail: if (grub_errno == GRUB_ERR_OUT_OF_RANGE) - grub_error (GRUB_ERR_BAD_FS, "not an affs filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not an AFFS filesystem"); grub_free (data); grub_free (rootblock); diff --git a/fs/cpio.c b/fs/cpio.c index 59b5f7734..b5e372f7c 100644 --- a/fs/cpio.c +++ b/fs/cpio.c @@ -88,7 +88,7 @@ grub_cpio_find_file (struct grub_cpio_data *data, char **name, return grub_errno; if (hd.magic != MAGIC_BCPIO) - return grub_error (GRUB_ERR_BAD_FS, "Invalid cpio archive"); + return grub_error (GRUB_ERR_BAD_FS, "invalid cpio archive"); data->size = (((grub_uint32_t) hd.filesize_1) << 16) + hd.filesize_2; @@ -130,7 +130,7 @@ grub_cpio_find_file (struct grub_cpio_data *data, char **name, } if (grub_memcmp (hd.magic, MAGIC_USTAR, sizeof (MAGIC_USTAR) - 1)) - return grub_error (GRUB_ERR_BAD_FS, "Invalid tar archive"); + return grub_error (GRUB_ERR_BAD_FS, "invalid tar archive"); if ((*name = grub_strdup (hd.name)) == NULL) return grub_errno; diff --git a/fs/fat.c b/fs/fat.c index e7f01629e..8a0fc0292 100644 --- a/fs/fat.c +++ b/fs/fat.c @@ -25,6 +25,7 @@ #include #include #include +#include #define GRUB_FAT_DIR_ENTRY_SIZE 32 @@ -337,7 +338,7 @@ grub_fat_mount (grub_disk_t disk) fail: grub_free (data); - grub_error (GRUB_ERR_BAD_FS, "not a fat filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not a FAT filesystem"); return 0; } diff --git a/fs/hfs.c b/fs/hfs.c index 5062b5f71..4dd1e3131 100644 --- a/fs/hfs.c +++ b/fs/hfs.c @@ -365,7 +365,7 @@ grub_hfs_mount (grub_disk_t disk) if (grub_hfs_find_node (data, (char *) &key, data->cat_root, 0, (char *) &dir, sizeof (dir)) == 0) { - grub_error (GRUB_ERR_BAD_FS, "can not find the hfs root directory"); + grub_error (GRUB_ERR_BAD_FS, "cannot find the HFS root directory"); goto fail; } @@ -379,7 +379,7 @@ grub_hfs_mount (grub_disk_t disk) grub_free (data); if (grub_errno == GRUB_ERR_OUT_OF_RANGE) - grub_error (GRUB_ERR_BAD_FS, "not a hfs filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not a HFS filesystem"); return 0; } @@ -1072,6 +1072,31 @@ grub_hfs_label (grub_device_t device, char **label) return grub_errno; } +static grub_err_t +grub_hfs_uuid (grub_device_t device, char **uuid) +{ + struct grub_hfs_data *data; + + grub_dl_ref (my_mod); + + data = grub_hfs_mount (device->disk); + if (data && data->sblock.num_serial != 0) + { + *uuid = grub_malloc (16 + sizeof ('\0')); + grub_sprintf (*uuid, "%016llx", + (unsigned long long) + grub_be_to_cpu64 (data->sblock.num_serial)); + } + else + *uuid = NULL; + + grub_dl_unref (my_mod); + + grub_free (data); + + return grub_errno; +} + static struct grub_fs grub_hfs_fs = @@ -1082,6 +1107,7 @@ static struct grub_fs grub_hfs_fs = .read = grub_hfs_read, .close = grub_hfs_close, .label = grub_hfs_label, + .uuid = grub_hfs_uuid, .next = 0 }; diff --git a/fs/hfsplus.c b/fs/hfsplus.c index b306e8d6a..9310b6502 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 @@ -501,7 +502,7 @@ grub_hfsplus_mount (grub_disk_t disk) fail: if (grub_errno == GRUB_ERR_OUT_OF_RANGE) - grub_error (GRUB_ERR_BAD_FS, "not a hfsplus filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not a HFS+ filesystem"); grub_free (data); return 0; @@ -652,7 +653,7 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree, btree->nodesize, (char *) node) <= 0) { grub_free (node); - return grub_error (GRUB_ERR_BAD_FS, "Couldn't read i-node."); + return grub_error (GRUB_ERR_BAD_FS, "couldn't read i-node"); } nodedesc = (struct grub_hfsplus_btnode *) node; diff --git a/fs/i386/pc/pxe.c b/fs/i386/pc/pxe.c index 6c41d4298..03385b3e3 100644 --- a/fs/i386/pc/pxe.c +++ b/fs/i386/pc/pxe.c @@ -1,7 +1,7 @@ /* pxe.c - Driver to provide access to the pxe filesystem */ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2008 Free Software Foundation, Inc. + * Copyright (C) 2008,2009 Free Software Foundation, Inc. * * GRUB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -33,11 +34,17 @@ #define SEGOFS(x) ((SEGMENT(x) << 16) + OFFSET(x)) #define LINEAR(x) (void *) (((x >> 16) <<4) + (x & 0xFFFF)) +struct grub_pxe_disk_data +{ + grub_uint32_t server_ip; + grub_uint32_t gateway_ip; +}; + struct grub_pxenv *grub_pxe_pxenv; -grub_uint32_t grub_pxe_your_ip; -grub_uint32_t grub_pxe_server_ip; -grub_uint32_t grub_pxe_gateway_ip; -int grub_pxe_blksize = GRUB_PXE_MIN_BLKSIZE; +static grub_uint32_t grub_pxe_your_ip; +static grub_uint32_t grub_pxe_default_server_ip; +static grub_uint32_t grub_pxe_default_gateway_ip; +static unsigned grub_pxe_blksize = GRUB_PXE_MIN_BLKSIZE; static grub_file_t curr_file = 0; @@ -56,24 +63,83 @@ grub_pxe_iterate (int (*hook) (const char *name)) return 0; } +static grub_err_t +parse_ip (const char *val, grub_uint32_t *ip, const char **rest) +{ + grub_uint32_t newip = 0; + unsigned long t; + int i; + const char *ptr = val; + + for (i = 0; i < 4; i++) + { + t = grub_strtoul (ptr, (char **) &ptr, 0); + if (grub_errno) + return grub_errno; + if (t & ~0xff) + return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); + newip >>= 8; + newip |= (t << 24); + if (i != 3 && *ptr != '.') + return grub_error (GRUB_ERR_OUT_OF_RANGE, "Invalid IP."); + ptr++; + } + *ip = newip; + if (rest) + *rest = ptr - 1; + return 0; +} + static grub_err_t grub_pxe_open (const char *name, grub_disk_t disk) { - if (grub_strcmp (name, "pxe")) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a pxe disk"); + struct grub_pxe_disk_data *data; + + if (grub_strcmp (name, "pxe") != 0 + && grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) != 0) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a pxe disk"); + + data = grub_malloc (sizeof (*data)); + if (!data) + return grub_errno; + + if (grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) == 0) + { + const char *ptr; + grub_err_t err; + + ptr = name + sizeof ("pxe:") - 1; + err = parse_ip (ptr, &(data->server_ip), &ptr); + if (err) + return err; + if (*ptr == ':') + { + err = parse_ip (ptr + 1, &(data->server_ip), 0); + if (err) + return err; + } + else + data->gateway_ip = grub_pxe_default_gateway_ip; + } + else + { + data->server_ip = grub_pxe_default_server_ip; + data->gateway_ip = grub_pxe_default_gateway_ip; + } disk->total_sectors = 0; - disk->id = (unsigned long) "pxe"; + disk->id = (unsigned long) data; disk->has_partitions = 0; - disk->data = 0; + disk->data = data; return GRUB_ERR_NONE; } static void -grub_pxe_close (grub_disk_t disk __attribute((unused))) +grub_pxe_close (grub_disk_t disk) { + grub_free (disk->data); } static grub_err_t @@ -107,9 +173,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; } @@ -123,6 +191,7 @@ grub_pxefs_open (struct grub_file *file, const char *name) struct grub_pxenv_tftp_open c2; } c; struct grub_pxe_data *data; + struct grub_pxe_disk_data *disk_data = file->device->disk->data; grub_file_t file_int, bufio; if (curr_file != 0) @@ -131,8 +200,8 @@ grub_pxefs_open (struct grub_file *file, const char *name) curr_file = 0; } - c.c1.server_ip = grub_pxe_server_ip; - c.c1.gateway_ip = grub_pxe_gateway_ip; + c.c1.server_ip = disk_data->server_ip; + c.c1.gateway_ip = disk_data->gateway_ip; grub_strcpy ((char *)&c.c1.filename[0], name); grub_pxe_call (GRUB_PXENV_TFTP_GET_FSIZE, &c.c1); if (c.c1.status) @@ -182,6 +251,7 @@ grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len) { struct grub_pxenv_tftp_read c; struct grub_pxe_data *data; + struct grub_pxe_disk_data *disk_data = file->device->disk->data; grub_uint32_t pn, r; data = file->data; @@ -201,8 +271,8 @@ grub_pxefs_read (grub_file_t file, char *buf, grub_size_t len) if (curr_file != 0) grub_pxe_call (GRUB_PXENV_TFTP_CLOSE, &o); - o.server_ip = grub_pxe_server_ip; - o.gateway_ip = grub_pxe_gateway_ip; + o.server_ip = disk_data->server_ip; + o.gateway_ip = disk_data->gateway_ip; grub_strcpy ((char *)&o.filename[0], data->filename); o.tftp_port = grub_cpu_to_be16 (GRUB_PXE_TFTP_PORT); o.packet_size = grub_pxe_blksize; @@ -270,6 +340,99 @@ static struct grub_fs grub_pxefs_fs = .next = 0 }; +static char * +grub_env_write_readonly (struct grub_env_var *var __attribute__ ((unused)), + const char *val __attribute__ ((unused))) +{ + return NULL; +} + +static void +set_mac_env (grub_uint8_t *mac_addr, grub_size_t mac_len) +{ + char buf[(sizeof ("XX:") - 1) * mac_len + 1]; + char *ptr = buf; + unsigned i; + + for (i = 0; i < mac_len; i++) + { + grub_sprintf (ptr, "%02x:", mac_addr[i] & 0xff); + ptr += (sizeof ("XX:") - 1); + } + if (mac_len) + *(ptr - 1) = 0; + else + buf[0] = 0; + + grub_env_set ("net_pxe_mac", buf); + /* XXX: Is it possible to change MAC in PXE? */ + grub_register_variable_hook ("net_pxe_mac", 0, grub_env_write_readonly); +} + +static void +set_env_limn_ro (const char *varname, char *value, grub_size_t len) +{ + char c; + c = value[len]; + value[len] = 0; + grub_env_set (varname, value); + value[len] = c; + grub_register_variable_hook (varname, 0, grub_env_write_readonly); +} + +static void +parse_dhcp_vendor (void *vend, int limit) +{ + grub_uint8_t *ptr, *ptr0; + + ptr = ptr0 = vend; + + if (grub_be_to_cpu32 (*(grub_uint32_t *) ptr) != 0x63825363) + return; + ptr = ptr + sizeof (grub_uint32_t); + while (ptr - ptr0 < limit) + { + grub_uint8_t tagtype; + grub_uint8_t taglength; + + tagtype = *ptr++; + + /* Pad tag. */ + if (tagtype == 0) + continue; + + /* End tag. */ + if (tagtype == 0xff) + return; + + taglength = *ptr++; + + switch (tagtype) + { + case 12: + set_env_limn_ro ("net_pxe_hostname", (char *) ptr, taglength); + break; + + case 15: + set_env_limn_ro ("net_pxe_domain", (char *) ptr, taglength); + break; + + case 17: + set_env_limn_ro ("net_pxe_rootpath", (char *) ptr, taglength); + break; + + case 18: + set_env_limn_ro ("net_pxe_extensionspath", (char *) ptr, taglength); + break; + + /* If you need any other options please contact GRUB + developpement team. */ + } + + ptr += taglength; + } +} + static void grub_pxe_detect (void) { @@ -291,9 +454,15 @@ grub_pxe_detect (void) bp = LINEAR (ci.buffer); grub_pxe_your_ip = bp->your_ip; - grub_pxe_server_ip = bp->server_ip; - grub_pxe_gateway_ip = bp->gateway_ip; - + grub_pxe_default_server_ip = bp->server_ip; + grub_pxe_default_gateway_ip = bp->gateway_ip; + set_mac_env (bp->mac_addr, bp->hw_len < sizeof (bp->mac_addr) ? bp->hw_len + : sizeof (bp->mac_addr)); + set_env_limn_ro ("net_pxe_boot_file", (char *) bp->boot_file, + sizeof (bp->boot_file)); + set_env_limn_ro ("net_pxe_dhcp_server_name", (char *) bp->server_name, + sizeof (bp->server_name)); + parse_dhcp_vendor (&bp->vendor, sizeof (bp->vendor)); grub_pxe_pxenv = pxenv; } @@ -309,11 +478,110 @@ grub_pxe_unload (void) } } +static void +set_ip_env (char *varname, grub_uint32_t ip) +{ + char buf[sizeof ("XXX.XXX.XXX.XXX")]; + + grub_sprintf (buf, "%d.%d.%d.%d", (ip & 0xff), + (ip >> 8) & 0xff, (ip >> 16) & 0xff, (ip >> 24) & 0xff); + grub_env_set (varname, buf); +} + +static char * +write_ip_env (grub_uint32_t *ip, const char *val) +{ + char *buf; + grub_err_t err; + grub_uint32_t newip; + + err = parse_ip (val, &newip, 0); + if (err) + return 0; + + /* Normalize the IP. */ + buf = grub_malloc (sizeof ("XXX.XXX.XXX.XXX")); + if (!buf) + return 0; + + *ip = newip; + + grub_sprintf (buf, "%d.%d.%d.%d", (newip & 0xff), (newip >> 8) & 0xff, + (newip >> 16) & 0xff, (newip >> 24) & 0xff); + + return buf; +} + +static char * +grub_env_write_pxe_default_server (struct grub_env_var *var + __attribute__ ((unused)), + const char *val) +{ + return write_ip_env (&grub_pxe_default_server_ip, val); +} + +static char * +grub_env_write_pxe_default_gateway (struct grub_env_var *var + __attribute__ ((unused)), + const char *val) +{ + return write_ip_env (&grub_pxe_default_gateway_ip, val); +} + +static char * +grub_env_write_pxe_blocksize (struct grub_env_var *var __attribute__ ((unused)), + const char *val) +{ + unsigned size; + char *buf; + + size = grub_strtoul (val, 0, 0); + if (grub_errno) + return 0; + + if (size < GRUB_PXE_MIN_BLKSIZE) + size = GRUB_PXE_MIN_BLKSIZE; + else if (size > GRUB_PXE_MAX_BLKSIZE) + size = GRUB_PXE_MAX_BLKSIZE; + + buf = grub_malloc (sizeof ("XXXXXX XXXXXX")); + if (!buf) + return 0; + + grub_sprintf (buf, "%d", size); + grub_pxe_blksize = size; + + return buf; +} + + GRUB_MOD_INIT(pxe) { grub_pxe_detect (); if (grub_pxe_pxenv) { + char *buf; + + buf = grub_malloc (sizeof ("XXXXXX XXXXXX")); + if (buf) + { + grub_sprintf (buf, "%d", grub_pxe_blksize); + grub_env_set ("net_pxe_blksize", buf); + } + + set_ip_env ("pxe_default_server", grub_pxe_default_server_ip); + set_ip_env ("pxe_default_gateway", grub_pxe_default_gateway_ip); + set_ip_env ("net_pxe_ip", grub_pxe_your_ip); + grub_register_variable_hook ("net_pxe_default_server", 0, + grub_env_write_pxe_default_server); + grub_register_variable_hook ("net_pxe_default_gateway", 0, + grub_env_write_pxe_default_gateway); + + /* XXX: Is it possible to change IP in PXE? */ + grub_register_variable_hook ("net_pxe_ip", 0, + grub_env_write_readonly); + grub_register_variable_hook ("net_pxe_blksize", 0, + grub_env_write_pxe_blocksize); grub_disk_dev_register (&grub_pxe_dev); grub_fs_register (&grub_pxefs_fs); } diff --git a/fs/iso9660.c b/fs/iso9660.c index 9b7ce765b..2fb0ffb63 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 @@ -279,13 +280,13 @@ grub_iso9660_mount (grub_disk_t disk) sizeof (struct grub_iso9660_primary_voldesc), (char *) &voldesc)) { - grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); goto fail; } if (grub_strncmp ((char *) voldesc.voldesc.magic, "CD001", 5) != 0) { - grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); goto fail; } @@ -314,7 +315,7 @@ grub_iso9660_mount (grub_disk_t disk) << GRUB_ISO9660_LOG2_BLKSZ), 0, sizeof (rootdir), (char *) &rootdir)) { - grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); goto fail; } @@ -330,7 +331,7 @@ grub_iso9660_mount (grub_disk_t disk) << GRUB_ISO9660_LOG2_BLKSZ), sua_pos, sua_size, sua)) { - grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not a ISO9660 filesystem"); goto fail; } @@ -831,7 +832,7 @@ grub_iso9660_uuid (grub_device_t device, char **uuid) && ! data->voldesc.modified.second[0] && ! data->voldesc.modified.second[1] && ! data->voldesc.modified.hundredth[0] && ! data->voldesc.modified.hundredth[1]) { - grub_error (GRUB_ERR_BAD_NUMBER, "No creation date in filesystem to generate UUID."); + grub_error (GRUB_ERR_BAD_NUMBER, "no creation date in filesystem to generate UUID"); *uuid = NULL; } else diff --git a/fs/jfs.c b/fs/jfs.c index b73f9bdd4..dc5eaed67 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 @@ -343,7 +344,7 @@ grub_jfs_mount (grub_disk_t disk) if (grub_strncmp ((char *) (data->sblock.magic), "JFS1", 4)) { - grub_error (GRUB_ERR_BAD_FS, "not a jfs filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not a JFS filesystem"); goto fail; } @@ -362,7 +363,7 @@ grub_jfs_mount (grub_disk_t disk) grub_free (data); if (grub_errno == GRUB_ERR_OUT_OF_RANGE) - grub_error (GRUB_ERR_BAD_FS, "not a jfs filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not a JFS filesystem"); return 0; } @@ -714,7 +715,7 @@ grub_jfs_lookup_symlink (struct grub_jfs_data *data, int ino) grub_jfs_find_file (data, symlink); if (grub_errno) - grub_error (grub_errno, "Can not follow symlink `%s'.", symlink); + grub_error (grub_errno, "cannot follow symlink `%s'", symlink); return grub_errno; } diff --git a/fs/minix.c b/fs/minix.c index 08eb60729..a856e38c4 100644 --- a/fs/minix.c +++ b/fs/minix.c @@ -311,7 +311,7 @@ grub_minix_lookup_symlink (struct grub_minix_data *data, int ino) grub_minix_find_file (data, symlink); if (grub_errno) - grub_error (grub_errno, "Can not follow symlink `%s'.", symlink); + grub_error (grub_errno, "cannot follow symlink `%s'", symlink); return grub_errno; } diff --git a/fs/ntfs.c b/fs/ntfs.c index c780887c6..87db1a561 100644 --- a/fs/ntfs.c +++ b/fs/ntfs.c @@ -24,6 +24,7 @@ #include #include #include +#include static grub_dl_t my_mod; @@ -41,7 +42,7 @@ fixup (struct grub_ntfs_data *data, char *buf, int len, char *magic) ss = u16at (buf, 6) - 1; if (ss * (int) data->blocksize != len * GRUB_DISK_SECTOR_SIZE) - return grub_error (GRUB_ERR_BAD_FS, "Size not match", + return grub_error (GRUB_ERR_BAD_FS, "size not match", ss * (int) data->blocksize, len * GRUB_DISK_SECTOR_SIZE); pu = buf + u16at (buf, 4); @@ -52,7 +53,7 @@ fixup (struct grub_ntfs_data *data, char *buf, int len, char *magic) buf += data->blocksize; pu += 2; if (u16at (buf, 0) != us) - return grub_error (GRUB_ERR_BAD_FS, "Fixup signature not match"); + return grub_error (GRUB_ERR_BAD_FS, "fixup signature not match"); v16at (buf, 0) = v16at (pu, 0); ss--; } @@ -146,7 +147,7 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) new_pos += u16at (new_pos, 4); } grub_error (GRUB_ERR_BAD_FS, - "Can\'t find 0x%X in attribute list", + "can\'t find 0x%X in attribute list", (unsigned char) *at->attr_cur); return NULL; } @@ -185,7 +186,7 @@ find_attr (struct grub_ntfs_attr *at, unsigned char attr) if (read_data (at, pa, at->edat_buf, 0, n, 0, 0)) { grub_error (GRUB_ERR_BAD_FS, - "Fail to read non-resident attribute list"); + "fail to read non-resident attribute list"); return NULL; } at->attr_nxt = at->edat_buf; @@ -314,7 +315,7 @@ retry: goto retry; } } - return grub_error (GRUB_ERR_BAD_FS, "Run list overflown"); + return grub_error (GRUB_ERR_BAD_FS, "run list overflown"); } run = read_run_data (run + 1, c1, &val, 0); /* length of current VCN */ ctx->curr_vcn = ctx->next_vcn; @@ -368,7 +369,7 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, if (pa[8] == 0) { if (ofs + len > u32at (pa, 0x10)) - return grub_error (GRUB_ERR_BAD_FS, "Read out of range"); + return grub_error (GRUB_ERR_BAD_FS, "read out of range"); grub_memcpy (dest, pa + u32at (pa, 0x14) + ofs, len); return 0; } @@ -382,7 +383,7 @@ read_data (struct grub_ntfs_attr *at, char *pa, char *dest, if (ctx->flags & RF_COMP) { if (!cached) - return grub_error (GRUB_ERR_BAD_FS, "Attribute can\'t be compressed"); + return grub_error (GRUB_ERR_BAD_FS, "attribute can\'t be compressed"); if (at->sbuf) { @@ -501,7 +502,7 @@ read_attr (struct grub_ntfs_attr *at, char *dest, grub_disk_addr_t ofs, else ret = (grub_errno) ? grub_errno : grub_error (GRUB_ERR_BAD_FS, - "Attribute not found"); + "attribute not found"); at->attr_cur = save_cur; return ret; } @@ -512,7 +513,7 @@ read_mft (struct grub_ntfs_data *data, char *buf, grub_uint32_t mftno) if (read_attr (&data->mmft.attr, buf, mftno * ((grub_disk_addr_t) data->mft_size << BLK_SHR), data->mft_size << BLK_SHR, 0, 0)) - return grub_error (GRUB_ERR_BAD_FS, "Read MFT 0x%X fails", mftno); + return grub_error (GRUB_ERR_BAD_FS, "read MFT 0x%X fails", mftno); return fixup (data, buf, data->mft_size, "FILE"); } @@ -540,7 +541,7 @@ init_file (struct grub_ntfs_file *mft, grub_uint32_t mftno) pa = locate_attr (&mft->attr, mft, AT_DATA); if (pa == NULL) - return grub_error (GRUB_ERR_BAD_FS, "No $DATA in MFT 0x%X", mftno); + return grub_error (GRUB_ERR_BAD_FS, "no $DATA in MFT 0x%X", mftno); if (!pa[8]) mft->size = u32at (pa, 0x10); @@ -663,7 +664,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, { if ((cur_pos = find_attr (at, AT_INDEX_ROOT)) == NULL) { - grub_error (GRUB_ERR_BAD_FS, "No $INDEX_ROOT"); + grub_error (GRUB_ERR_BAD_FS, "no $INDEX_ROOT"); goto done; } @@ -716,7 +717,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir, if (read_data (at, cur_pos, bmp, 0, bitmap_len, 0, 0)) { grub_error (GRUB_ERR_BAD_FS, - "Fails to read non-resident $BITMAP"); + "fails to read non-resident $BITMAP"); goto done; } bitmap_len = u32at (cur_pos, 0x30); diff --git a/fs/ntfscomp.c b/fs/ntfscomp.c index 6bb33ffb1..c29979edc 100644 --- a/fs/ntfscomp.c +++ b/fs/ntfscomp.c @@ -28,7 +28,7 @@ static grub_err_t decomp_nextvcn (struct grub_ntfs_comp *cc) { if (cc->comp_head >= cc->comp_tail) - return grub_error (GRUB_ERR_BAD_FS, "Compression block overflown"); + return grub_error (GRUB_ERR_BAD_FS, "compression block overflown"); if (grub_disk_read (cc->disk, (cc->comp_table[cc->comp_head][1] - @@ -87,7 +87,7 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest) { if (copied > COM_LEN) return grub_error (GRUB_ERR_BAD_FS, - "Compression block too large"); + "compression block too large"); if (!bits) { @@ -112,7 +112,7 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest) if (!copied) { - grub_error (GRUB_ERR_BAD_FS, "Context window empty"); + grub_error (GRUB_ERR_BAD_FS, "nontext window empty"); return 0; } @@ -150,7 +150,7 @@ decomp_block (struct grub_ntfs_comp *cc, char *dest) { if (cnt != COM_LEN) return grub_error (GRUB_ERR_BAD_FS, - "Invalid compression block size"); + "invalid compression block size"); } } @@ -187,7 +187,7 @@ read_block (struct grub_ntfs_rlst *ctx, char *buf, int num) { if (ctx->comp.comp_head != ctx->comp.comp_tail) - return grub_error (GRUB_ERR_BAD_FS, "Invalid compression block"); + return grub_error (GRUB_ERR_BAD_FS, "invalid compression block"); ctx->comp.comp_head = ctx->comp.comp_tail = 0; ctx->comp.cbuf_vcn = ctx->target_vcn; ctx->comp.cbuf_ofs = (ctx->comp.spc << BLK_SHR); diff --git a/fs/reiserfs.c b/fs/reiserfs.c index fb4f1bc59..a8ba75910 100644 --- a/fs/reiserfs.c +++ b/fs/reiserfs.c @@ -691,7 +691,7 @@ grub_reiserfs_mount (grub_disk_t disk) if (grub_memcmp (data->superblock.magic_string, REISERFS_MAGIC_STRING, sizeof (REISERFS_MAGIC_STRING) - 1)) { - grub_error (GRUB_ERR_BAD_FS, "not a reiserfs filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not a ReiserFS filesystem"); goto fail; } data->disk = disk; @@ -700,7 +700,7 @@ grub_reiserfs_mount (grub_disk_t disk) fail: /* Disk is too small to contain a ReiserFS. */ if (grub_errno == GRUB_ERR_OUT_OF_RANGE) - grub_error (GRUB_ERR_BAD_FS, "not a reiserfs filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not a ReiserFS filesystem"); grub_free (data); return 0; @@ -998,7 +998,7 @@ grub_reiserfs_open (struct grub_file *file, const char *name) goto fail; if (root.block_number == 0) { - grub_error (GRUB_ERR_BAD_FS, "Unable to find root item"); + grub_error (GRUB_ERR_BAD_FS, "unable to find root item"); goto fail; /* Should never happen since checked at mount. */ } grub_fshelp_find_file (name, &root, &found, @@ -1014,7 +1014,7 @@ grub_reiserfs_open (struct grub_file *file, const char *name) goto fail; if (info.block_number == 0) { - grub_error (GRUB_ERR_BAD_FS, "Unable to find searched item"); + grub_error (GRUB_ERR_BAD_FS, "unable to find searched item"); goto fail; } entry_version = grub_le_to_cpu16 (info.header.version); @@ -1289,7 +1289,7 @@ grub_reiserfs_dir (grub_device_t device, const char *path, goto fail; if (root.block_number == 0) { - grub_error(GRUB_ERR_BAD_FS, "Root not found"); + grub_error(GRUB_ERR_BAD_FS, "root not found"); goto fail; } grub_fshelp_find_file (path, &root, &found, grub_reiserfs_iterate_dir, diff --git a/fs/sfs.c b/fs/sfs.c index ec59b73ca..4f70ad3ec 100644 --- a/fs/sfs.c +++ b/fs/sfs.c @@ -279,7 +279,7 @@ grub_sfs_mount (grub_disk_t disk) /* Make sure this is a sfs filesystem. */ if (grub_strncmp ((char *) (data->rblock.header.magic), "SFS", 4)) { - grub_error (GRUB_ERR_BAD_FS, "not a sfs filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not a SFS filesystem"); goto fail; } @@ -307,7 +307,7 @@ grub_sfs_mount (grub_disk_t disk) fail: if (grub_errno == GRUB_ERR_OUT_OF_RANGE) - grub_error (GRUB_ERR_BAD_FS, "not an sfs filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not an SFS filesystem"); grub_free (data); grub_free (rootobjc_data); diff --git a/fs/udf.c b/fs/udf.c index 9dfe431f6..b44fa8a6d 100644 --- a/fs/udf.c +++ b/fs/udf.c @@ -525,7 +525,7 @@ grub_udf_mount (grub_disk_t disk) if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0, sizeof (struct grub_udf_vrs), &vrs)) { - grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); goto fail; } @@ -539,7 +539,7 @@ grub_udf_mount (grub_disk_t disk) (grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_CDW02, 5)) && (grub_memcmp (vrs.magic, GRUB_UDF_STD_IDENT_TEA01, 5))) { - grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); goto fail; } } @@ -552,7 +552,7 @@ grub_udf_mount (grub_disk_t disk) if (grub_disk_read (disk, *sblklist << GRUB_UDF_LOG2_BLKSZ, 0, sizeof (struct grub_udf_avdp), &avdp)) { - grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); goto fail; } @@ -565,7 +565,7 @@ grub_udf_mount (grub_disk_t disk) sblklist++; if (*sblklist == 0) { - grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); goto fail; } } @@ -579,7 +579,7 @@ grub_udf_mount (grub_disk_t disk) if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0, sizeof (struct grub_udf_tag), &tag)) { - grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); goto fail; } @@ -596,7 +596,7 @@ grub_udf_mount (grub_disk_t disk) sizeof (struct grub_udf_pd), &data->pds[data->npd])) { - grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); goto fail; } @@ -612,7 +612,7 @@ grub_udf_mount (grub_disk_t disk) sizeof (struct grub_udf_lvd), &data->lvd)) { - grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); goto fail; } @@ -675,7 +675,7 @@ grub_udf_mount (grub_disk_t disk) if (grub_disk_read (disk, block << GRUB_UDF_LOG2_BLKSZ, 0, sizeof (struct grub_udf_fileset), &root_fs)) { - grub_error (GRUB_ERR_BAD_FS, "not an udf filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not an UDF filesystem"); goto fail; } diff --git a/fs/ufs.c b/fs/ufs.c index c94ad9922..f95a6e12e 100644 --- a/fs/ufs.c +++ b/fs/ufs.c @@ -415,7 +415,7 @@ grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino) grub_ufs_find_file (data, symlink); if (grub_errno) - grub_error (grub_errno, "Can not follow symlink `%s'.", symlink); + grub_error (grub_errno, "cannot follow symlink `%s'", symlink); return grub_errno; } diff --git a/fs/xfs.c b/fs/xfs.c index 1b18bef3b..c15ec7341 100644 --- a/fs/xfs.c +++ b/fs/xfs.c @@ -222,7 +222,7 @@ grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino, return grub_errno; if (grub_strncmp ((char *) inode->magic, "IN", 2)) - return grub_error (GRUB_ERR_BAD_FS, "not a correct XFS inode.\n"); + return grub_error (GRUB_ERR_BAD_FS, "not a correct XFS inode"); return 0; } @@ -273,7 +273,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) if (grub_strncmp ((char *) leaf->magic, "BMAP", 4)) { grub_free (leaf); - grub_error (GRUB_ERR_BAD_FS, "not a correct XFS BMAP node.\n"); + grub_error (GRUB_ERR_BAD_FS, "not a correct XFS BMAP node"); return 0; } @@ -290,7 +290,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock) else { grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "xfs does not support inode format %d yet", + "XFS does not support inode format %d yet", node->inode.format); return 0; } @@ -567,7 +567,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, default: grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "xfs does not support inode format %d yet", + "XFS does not support inode format %d yet", diro->inode.format); } return 0; @@ -590,7 +590,7 @@ grub_xfs_mount (grub_disk_t disk) if (grub_strncmp ((char *) (data->sblock.magic), "XFSB", 4)) { - grub_error (GRUB_ERR_BAD_FS, "not a xfs filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not a XFS filesystem"); goto fail; } @@ -617,7 +617,7 @@ grub_xfs_mount (grub_disk_t disk) fail: if (grub_errno == GRUB_ERR_OUT_OF_RANGE) - grub_error (GRUB_ERR_BAD_FS, "not an xfs filesystem"); + grub_error (GRUB_ERR_BAD_FS, "not an XFS filesystem"); grub_free (data); diff --git a/gendistlist.sh b/gendistlist.sh index 43366bd73..102c0c11c 100755 --- a/gendistlist.sh +++ b/gendistlist.sh @@ -36,7 +36,7 @@ dir=`dirname $0` cd $dir for dir in $DISTDIRS; do - for d in `find $dir -type d -not -name .svn -not -name .bzr | sort`; do + for d in `find $dir -type d ! -name .svn ! -name .bzr | sort`; do find $d -maxdepth 1 -name '*.[chSy]' -o -name '*.mk' -o -name '*.rmk' \ -o -name '*.rb' -o -name '*.in' -o -name '*.tex' -o -name '*.texi' \ -o -name '*.info' -o -name 'grub.cfg' -o -name 'README' \ diff --git a/genmk.rb b/genmk.rb index 9fa295a37..6519bdd0c 100644 --- a/genmk.rb +++ b/genmk.rb @@ -366,6 +366,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..c48b5fd95 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 . */ @@ -243,7 +243,7 @@ grub_mofile_open (const char *filename) if (version != 0) { grub_error (GRUB_ERR_BAD_FILE_TYPE, - "mo: invalid mo version in file: %s\n", filename); + "mo: invalid mo version in file: %s", filename); fd_mo = 0; return 0; } diff --git a/include/grub/at_keyboard.h b/include/grub/at_keyboard.h index ba8071f20..10421540a 100644 --- a/include/grub/at_keyboard.h +++ b/include/grub/at_keyboard.h @@ -1,6 +1,6 @@ /* * GRUB -- GRand Unified Bootloader - * Copyright (C) 2007,2008 Free Software Foundation, Inc. + * Copyright (C) 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 @@ #define CTRL 0x1d #define ALT 0x38 #define CAPS_LOCK 0x3a +#define NUM_LOCK 0x45 +#define SCROLL_LOCK 0x46 /* Used for sending commands to the controller. */ #define KEYBOARD_COMMAND_ISREADY(x) !((x) & 0x02) diff --git a/include/grub/auth.h b/include/grub/auth.h index da930eeda..99f9d7260 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_ACCESS_DENIED grub_error (GRUB_ERR_ACCESS_DENIED, "access denied") +#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/hfs.h b/include/grub/hfs.h index 08b947ccb..d93b9a2c9 100644 --- a/include/grub/hfs.h +++ b/include/grub/hfs.h @@ -48,7 +48,8 @@ struct grub_hfs_sblock /* A pascal style string that holds the volumename. */ grub_uint8_t volname[28]; - grub_uint8_t unused5[60]; + grub_uint8_t unused5[52]; + grub_uint64_t num_serial; grub_uint16_t embed_sig; struct grub_hfs_extent embed_extent; grub_uint8_t unused6[4]; diff --git a/include/grub/i386/macho.h b/include/grub/i386/macho.h index 61e72a71b..f22c21190 100644 --- a/include/grub/i386/macho.h +++ b/include/grub/i386/macho.h @@ -1,3 +1,26 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_CPU_MACHO_H +#define GRUB_CPU_MACHO_H 1 + +#include + #define GRUB_MACHO_CPUTYPE_IS_HOST32(x) ((x)==0x00000007) #define GRUB_MACHO_CPUTYPE_IS_HOST64(x) ((x)==0x01000007) @@ -9,3 +32,15 @@ struct grub_macho_thread32 grub_uint32_t entry_point; grub_uint8_t unknown2[20]; } __attribute__ ((packed)); + + +struct grub_macho_thread64 +{ + grub_uint32_t cmd; + grub_uint32_t cmdsize; + grub_uint8_t unknown1[0x88]; + grub_uint64_t entry_point; + grub_uint8_t unknown2[0x20]; +} __attribute__ ((packed)); + +#endif diff --git a/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/pc/pxe.h b/include/grub/i386/pc/pxe.h index 482132896..39f356c83 100644 --- a/include/grub/i386/pc/pxe.h +++ b/include/grub/i386/pc/pxe.h @@ -201,7 +201,7 @@ struct grub_pxenv_get_cached_info #define GRUB_PXE_MAC_ADDR_LEN 16 -typedef grub_uint8_t grub_pxe_mac_addr[GRUB_PXE_MAC_ADDR_LEN]; +typedef grub_uint8_t grub_pxe_mac_addr_t[GRUB_PXE_MAC_ADDR_LEN]; struct grub_pxenv_boot_player { @@ -216,7 +216,7 @@ struct grub_pxenv_boot_player grub_uint32_t your_ip; grub_uint32_t server_ip; grub_uint32_t gateway_ip; - grub_pxe_mac_addr mac_addr; + grub_pxe_mac_addr_t mac_addr; grub_uint8_t server_name[64]; grub_uint8_t boot_file[128]; union @@ -306,10 +306,6 @@ struct grub_pxenv * EXPORT_FUNC(grub_pxe_scan) (void); int EXPORT_FUNC(grub_pxe_call) (int func, void * data); extern struct grub_pxenv *grub_pxe_pxenv; -extern grub_uint32_t grub_pxe_your_ip; -extern grub_uint32_t grub_pxe_server_ip; -extern grub_uint32_t grub_pxe_gateway_ip; -extern int grub_pxe_blksize; void grub_pxe_unload (void); 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 1ab63ac0b..92fb460cf 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -172,6 +172,8 @@ void *EXPORT_FUNC(grub_memset) (void *s, int c, grub_size_t n); grub_size_t EXPORT_FUNC(grub_strlen) (const char *s); int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); int EXPORT_FUNC(grub_printf_) (const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); +int EXPORT_FUNC(grub_puts) (const char *s); +int EXPORT_FUNC(grub_puts_) (const char *s); void EXPORT_FUNC(grub_real_dprintf) (const char *file, const int line, const char *condition, @@ -181,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/include/multiboot.h b/include/multiboot.h index 9ce34f437..587f50832 100644 --- a/include/multiboot.h +++ b/include/multiboot.h @@ -1,6 +1,5 @@ -/* - * multiboot.h - Multiboot header file. - * Copyright (C) 2003,2007,2008,2009 Free Software Foundation, Inc. +/* multiboot.h - Multiboot header file. */ +/* Copyright (C) 1999,2003,2007,2008,2009 Free Software Foundation, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -24,70 +23,66 @@ #define MULTIBOOT_HEADER 1 /* How many bytes from the start of the file we search for the header. */ -#define MULTIBOOT_SEARCH 8192 +#define MULTIBOOT_SEARCH 8192 /* The magic field should contain this. */ -#define MULTIBOOT_MAGIC 0x1BADB002 +#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 /* This should be in %eax. */ -#define MULTIBOOT_MAGIC2 0x2BADB002 +#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 /* The bits in the required part of flags field we don't support. */ -#define MULTIBOOT_UNSUPPORTED 0x0000fffc +#define MULTIBOOT_UNSUPPORTED 0x0000fffc /* Alignment of multiboot modules. */ -#define MULTIBOOT_MOD_ALIGN 0x00001000 +#define MULTIBOOT_MOD_ALIGN 0x00001000 /* Alignment of the multiboot info structure. */ -#define MULTIBOOT_INFO_ALIGN 0x00000004 +#define MULTIBOOT_INFO_ALIGN 0x00000004 -/* - * Flags set in the 'flags' member of the multiboot header. - */ +/* Flags set in the 'flags' member of the multiboot header. */ /* Align all boot modules on i386 page (4KB) boundaries. */ -#define MULTIBOOT_PAGE_ALIGN 0x00000001 +#define MULTIBOOT_PAGE_ALIGN 0x00000001 /* Must pass memory information to OS. */ -#define MULTIBOOT_MEMORY_INFO 0x00000002 +#define MULTIBOOT_MEMORY_INFO 0x00000002 /* Must pass video information to OS. */ -#define MULTIBOOT_VIDEO_MODE 0x00000004 +#define MULTIBOOT_VIDEO_MODE 0x00000004 /* This flag indicates the use of the address fields in the header. */ -#define MULTIBOOT_AOUT_KLUDGE 0x00010000 +#define MULTIBOOT_AOUT_KLUDGE 0x00010000 -/* - * Flags to be set in the 'flags' member of the multiboot info structure. - */ +/* Flags to be set in the 'flags' member of the multiboot info structure. */ /* is there basic lower/upper memory information? */ -#define MULTIBOOT_INFO_MEMORY 0x00000001 +#define MULTIBOOT_INFO_MEMORY 0x00000001 /* is there a boot device set? */ -#define MULTIBOOT_INFO_BOOTDEV 0x00000002 +#define MULTIBOOT_INFO_BOOTDEV 0x00000002 /* is the command-line defined? */ -#define MULTIBOOT_INFO_CMDLINE 0x00000004 +#define MULTIBOOT_INFO_CMDLINE 0x00000004 /* are there modules to do something with? */ -#define MULTIBOOT_INFO_MODS 0x00000008 +#define MULTIBOOT_INFO_MODS 0x00000008 /* These next two are mutually exclusive */ /* is there a symbol table loaded? */ #define MULTIBOOT_INFO_AOUT_SYMS 0x00000010 /* is there an ELF section header table? */ -#define MULTIBOOT_INFO_ELF_SHDR 0x00000020 +#define MULTIBOOT_INFO_ELF_SHDR 0X00000020 /* is there a full memory map? */ -#define MULTIBOOT_INFO_MEM_MAP 0x00000040 +#define MULTIBOOT_INFO_MEM_MAP 0x00000040 /* Is there drive info? */ #define MULTIBOOT_INFO_DRIVE_INFO 0x00000080 /* Is there a config table? */ -#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100 +#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100 /* Is there a boot loader name? */ -#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200 +#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200 /* Is there a APM table? */ #define MULTIBOOT_INFO_APM_TABLE 0x00000400 @@ -97,102 +92,131 @@ #ifndef ASM_FILE -#include +typedef unsigned short multiboot_uint16_t; +typedef unsigned int multiboot_uint32_t; +typedef unsigned long long multiboot_uint64_t; struct multiboot_header { /* Must be MULTIBOOT_MAGIC - see above. */ - grub_uint32_t magic; + multiboot_uint32_t magic; /* Feature flags. */ - grub_uint32_t flags; + multiboot_uint32_t flags; /* The above fields plus this one must equal 0 mod 2^32. */ - grub_uint32_t checksum; + multiboot_uint32_t checksum; /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ - grub_uint32_t header_addr; - grub_uint32_t load_addr; - grub_uint32_t load_end_addr; - grub_uint32_t bss_end_addr; - grub_uint32_t entry_addr; + multiboot_uint32_t header_addr; + multiboot_uint32_t load_addr; + multiboot_uint32_t load_end_addr; + multiboot_uint32_t bss_end_addr; + multiboot_uint32_t entry_addr; /* These are only valid if MULTIBOOT_VIDEO_MODE is set. */ - grub_uint32_t mode_type; - grub_uint32_t width; - grub_uint32_t height; - grub_uint32_t depth; + multiboot_uint32_t mode_type; + multiboot_uint32_t width; + multiboot_uint32_t height; + multiboot_uint32_t depth; }; +/* The symbol table for a.out. */ +struct multiboot_aout_symbol_table +{ + multiboot_uint32_t tabsize; + multiboot_uint32_t strsize; + multiboot_uint32_t addr; + multiboot_uint32_t reserved; +}; +typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t; + +/* The section header table for ELF. */ +struct multiboot_elf_section_header_table +{ + multiboot_uint32_t num; + multiboot_uint32_t size; + multiboot_uint32_t addr; + multiboot_uint32_t shndx; +}; +typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t; + struct multiboot_info { /* Multiboot info version number */ - grub_uint32_t flags; + multiboot_uint32_t flags; /* Available memory from BIOS */ - grub_uint32_t mem_lower; - grub_uint32_t mem_upper; + multiboot_uint32_t mem_lower; + multiboot_uint32_t mem_upper; /* "root" partition */ - grub_uint32_t boot_device; + multiboot_uint32_t boot_device; /* Kernel command line */ - grub_uint32_t cmdline; + multiboot_uint32_t cmdline; /* Boot-Module list */ - grub_uint32_t mods_count; - grub_uint32_t mods_addr; + multiboot_uint32_t mods_count; + multiboot_uint32_t mods_addr; - grub_uint32_t syms[4]; + union + { + multiboot_aout_symbol_table_t aout_sym; + multiboot_elf_section_header_table_t elf_sec; + } u; /* Memory Mapping buffer */ - grub_uint32_t mmap_length; - grub_uint32_t mmap_addr; + multiboot_uint32_t mmap_length; + multiboot_uint32_t mmap_addr; /* Drive Info buffer */ - grub_uint32_t drives_length; - grub_uint32_t drives_addr; + multiboot_uint32_t drives_length; + multiboot_uint32_t drives_addr; /* ROM configuration table */ - grub_uint32_t config_table; + multiboot_uint32_t config_table; /* Boot Loader Name */ - grub_uint32_t boot_loader_name; + multiboot_uint32_t boot_loader_name; /* APM table */ - grub_uint32_t apm_table; + multiboot_uint32_t apm_table; /* Video */ - grub_uint32_t vbe_control_info; - grub_uint32_t vbe_mode_info; - grub_uint16_t vbe_mode; - grub_uint16_t vbe_interface_seg; - grub_uint16_t vbe_interface_off; - grub_uint16_t vbe_interface_len; + multiboot_uint32_t vbe_control_info; + multiboot_uint32_t vbe_mode_info; + multiboot_uint16_t vbe_mode; + multiboot_uint16_t vbe_interface_seg; + multiboot_uint16_t vbe_interface_off; + multiboot_uint16_t vbe_interface_len; }; +typedef struct multiboot_info multiboot_info_t; struct multiboot_mmap_entry { - grub_uint32_t size; - grub_uint64_t addr; - grub_uint64_t len; + multiboot_uint32_t size; + multiboot_uint64_t addr; + multiboot_uint64_t len; #define MULTIBOOT_MEMORY_AVAILABLE 1 #define MULTIBOOT_MEMORY_RESERVED 2 - grub_uint32_t type; + multiboot_uint32_t type; } __attribute__((packed)); +typedef struct multiboot_mmap_entry multiboot_memory_map_t; struct multiboot_mod_list { /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */ - grub_uint32_t mod_start; - grub_uint32_t mod_end; + multiboot_uint32_t mod_start; + multiboot_uint32_t mod_end; /* Module command line */ - grub_uint32_t cmdline; + multiboot_uint32_t cmdline; /* padding to take it to 16 bytes (must be zero) */ - grub_uint32_t pad; + multiboot_uint32_t pad; }; +typedef struct multiboot_mod_list multiboot_module_t; #endif /* ! ASM_FILE */ 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 1e51839a0..0c5b4a3b4 100644 --- a/kern/elf.c +++ b/kern/elf.c @@ -74,7 +74,7 @@ grub_elf_file (grub_file_t file) != sizeof (elf->ehdr)) { grub_error_push (); - grub_error (GRUB_ERR_READ_ERROR, "Cannot read ELF header."); + grub_error (GRUB_ERR_READ_ERROR, "cannot read ELF header"); goto fail; } @@ -134,7 +134,7 @@ grub_elf32_load_phdrs (grub_elf_t elf) || (grub_file_read (elf->file, elf->phdrs, phdrs_size) != phdrs_size)) { grub_error_push (); - return grub_error (GRUB_ERR_READ_ERROR, "Cannot read program headers"); + return grub_error (GRUB_ERR_READ_ERROR, "cannot read program headers"); } return GRUB_ERR_NONE; @@ -181,7 +181,9 @@ grub_elf32_size (grub_elf_t elf, Elf32_Addr *base) /* 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) @@ -201,14 +203,14 @@ grub_elf32_size (grub_elf_t elf, Elf32_Addr *base) if (nr_phdrs == 0) { - grub_error (GRUB_ERR_BAD_OS, "No program headers present"); + grub_error (GRUB_ERR_BAD_OS, "no program headers present"); return 0; } if (segments_end < segments_start) { /* Very bad addresses. */ - grub_error (GRUB_ERR_BAD_OS, "Bad program header load addresses"); + grub_error (GRUB_ERR_BAD_OS, "bad program header load addresses"); return 0; } @@ -252,7 +254,7 @@ grub_elf32_load (grub_elf_t _elf, grub_elf32_load_hook_t _load_hook, { grub_error_push (); return grub_error (GRUB_ERR_BAD_OS, - "Invalid offset in program header."); + "invalid offset in program header"); } if (phdr->p_filesz) @@ -264,8 +266,8 @@ grub_elf32_load (grub_elf_t _elf, grub_elf32_load_hook_t _load_hook, /* XXX How can we free memory from `load_hook'? */ grub_error_push (); return grub_error (GRUB_ERR_BAD_OS, - "Couldn't read segment from file: " - "wanted 0x%lx bytes; read 0x%lx bytes.", + "couldn't read segment from file: " + "wanted 0x%lx bytes; read 0x%lx bytes", phdr->p_filesz, read); } } @@ -318,7 +320,7 @@ grub_elf64_load_phdrs (grub_elf_t elf) || (grub_file_read (elf->file, elf->phdrs, phdrs_size) != phdrs_size)) { grub_error_push (); - return grub_error (GRUB_ERR_READ_ERROR, "Cannot read program headers"); + return grub_error (GRUB_ERR_READ_ERROR, "cannot read program headers"); } return GRUB_ERR_NONE; @@ -365,7 +367,9 @@ grub_elf64_size (grub_elf_t elf, Elf64_Addr *base) /* 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) @@ -385,14 +389,14 @@ grub_elf64_size (grub_elf_t elf, Elf64_Addr *base) if (nr_phdrs == 0) { - grub_error (GRUB_ERR_BAD_OS, "No program headers present"); + grub_error (GRUB_ERR_BAD_OS, "no program headers present"); return 0; } if (segments_end < segments_start) { /* Very bad addresses. */ - grub_error (GRUB_ERR_BAD_OS, "Bad program header load addresses"); + grub_error (GRUB_ERR_BAD_OS, "bad program header load addresses"); return 0; } @@ -438,7 +442,7 @@ grub_elf64_load (grub_elf_t _elf, grub_elf64_load_hook_t _load_hook, { grub_error_push (); return grub_error (GRUB_ERR_BAD_OS, - "Invalid offset in program header."); + "invalid offset in program header"); } if (phdr->p_filesz) @@ -450,8 +454,8 @@ grub_elf64_load (grub_elf_t _elf, grub_elf64_load_hook_t _load_hook, /* XXX How can we free memory from `load_hook'? */ grub_error_push (); return grub_error (GRUB_ERR_BAD_OS, - "Couldn't read segment from file: " - "wanted 0x%lx bytes; read 0x%lx bytes.", + "couldn't read segment from file: " + "wanted 0x%lx bytes; read 0x%lx bytes", phdr->p_filesz, read); } } 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/file.c b/kern/file.c index f713acbca..4224cf910 100644 --- a/kern/file.c +++ b/kern/file.c @@ -115,7 +115,7 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len) if (file->offset > file->size) { grub_error (GRUB_ERR_OUT_OF_RANGE, - "Attempt to read past the end of file."); + "attempt to read past the end of file"); return -1; } diff --git a/kern/i386/coreboot/startup.S b/kern/i386/coreboot/startup.S index 3f2dd5f50..e94950aae 100644 --- a/kern/i386/coreboot/startup.S +++ b/kern/i386/coreboot/startup.S @@ -66,7 +66,7 @@ multiboot_header: .long -0x1BADB002 - MULTIBOOT_MEMORY_INFO codestart: - cmpl $MULTIBOOT_MAGIC2, %eax + cmpl $MULTIBOOT_BOOTLOADER_MAGIC, %eax jne 0f movl %ebx, EXT_C(startup_multiboot_info) 0: 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/ieee1275/init.c b/kern/ieee1275/init.c index 5d5d733d9..f3305d71c 100644 --- a/kern/ieee1275/init.c +++ b/kern/ieee1275/init.c @@ -164,7 +164,7 @@ static void grub_claim_heap (void) /* Claim and use it. */ if (grub_claimmap (addr, len) < 0) return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "Failed to claim heap at 0x%llx, len 0x%llx\n", + "failed to claim heap at 0x%llx, len 0x%llx", addr, len); grub_mm_init_region ((void *) (grub_addr_t) addr, len); } diff --git a/kern/ieee1275/mmap.c b/kern/ieee1275/mmap.c index 317a12117..6f0652770 100644 --- a/kern/ieee1275/mmap.c +++ b/kern/ieee1275/mmap.c @@ -44,11 +44,11 @@ grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uin /* Load `/memory/available'. */ if (grub_ieee1275_finddevice ("/memory", &memory)) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, - "Couldn't find /memory node"); + "couldn't find /memory node"); if (grub_ieee1275_get_integer_property (memory, "available", available, sizeof available, &available_size)) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, - "Couldn't examine /memory/available property"); + "couldn't examine /memory/available property"); /* Decode each entry and call `hook'. */ i = 0; diff --git a/kern/ieee1275/openfw.c b/kern/ieee1275/openfw.c index 9a2b0c9aa..c38eb450f 100644 --- a/kern/ieee1275/openfw.c +++ b/kern/ieee1275/openfw.c @@ -308,13 +308,13 @@ grub_ieee1275_parse_args (const char *path, enum grub_ieee1275_parse_type ptype) file path properly. */ if (grub_ieee1275_finddevice (device, &dev)) { - grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Device %s not found\n", device); + grub_error (GRUB_ERR_UNKNOWN_DEVICE, "device %s not found", device); goto fail; } if (grub_ieee1275_get_property (dev, "device_type", &type, sizeof type, 0)) { grub_error (GRUB_ERR_UNKNOWN_DEVICE, - "Device %s lacks a device_type property\n", device); + "device %s lacks a device_type property", device); goto fail; } diff --git a/kern/misc.c b/kern/misc.c index 4415b8204..f6d189e94 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -139,6 +139,25 @@ grub_printf_ (const char *fmt, ...) return ret; } +int +grub_puts (const char *s) +{ + while (*s) + { + grub_putchar (*s); + s++; + } + grub_putchar ('\n'); + + return 1; /* Cannot fail. */ +} + +int +grub_puts_ (const char *s) +{ + return grub_puts (_(s)); +} + #if defined (APPLE_CC) && ! defined (GRUB_UTIL) int grub_err_printf (const char *fmt, ...) @@ -860,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/powerpc/dl.c b/kern/powerpc/dl.c index 2891b0dbb..fa112b16f 100644 --- a/kern/powerpc/dl.c +++ b/kern/powerpc/dl.c @@ -106,7 +106,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) Elf_Sword delta = value - (Elf_Word) addr; if (delta << 6 >> 6 != delta) - return grub_error (GRUB_ERR_BAD_MODULE, "Relocation overflow"); + return grub_error (GRUB_ERR_BAD_MODULE, "relocation overflow"); *addr = (*addr & 0xfc000003) | (delta & 0x3fffffc); break; } @@ -125,7 +125,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) default: return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "This relocation (%d) is not implemented yet", + "this relocation (%d) is not implemented yet", ELF_R_TYPE (rel->r_info)); } } 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/kern/sparc64/dl.c b/kern/sparc64/dl.c index a4d99ff08..7932b4969 100644 --- a/kern/sparc64/dl.c +++ b/kern/sparc64/dl.c @@ -98,7 +98,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) case R_SPARC_32: /* 3 V-word32 */ if (value & 0xFFFFFFFF00000000) return grub_error (GRUB_ERR_BAD_MODULE, - "Address out of 32 bits range"); + "address out of 32 bits range"); *addr = value; break; case R_SPARC_WDISP30: /* 7 V-disp30 */ @@ -106,7 +106,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) (((value - (Elf_Addr) addr) & 0xFFFFFFFF00000000) != 0xFFFFFFFF00000000)) return grub_error (GRUB_ERR_BAD_MODULE, - "Displacement out of 30 bits range"); + "displacement out of 30 bits range"); *addr = (*addr & 0xC0000000) | (((grub_int32_t) ((value - (Elf_Addr) addr) >> 2)) & 0x3FFFFFFF); @@ -114,7 +114,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) case R_SPARC_HI22: /* 9 V-imm22 */ if (((grub_int32_t) value) & 0xFF00000000) return grub_error (GRUB_ERR_BAD_MODULE, - "High address out of 22 bits range"); + "high address out of 22 bits range"); *addr = (*addr & 0xFFC00000) | ((value >> 10) & 0x3FFFFF); break; case R_SPARC_LO10: /* 12 T-simm13 */ @@ -131,7 +131,7 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) break; default: return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "This relocation (%d) is not implemented yet", + "this relocation (%d) is not implemented yet", ELF_R_TYPE (rel->r_info)); } } diff --git a/lib/arg.c b/lib/arg.c index 24e9d5b15..bc1af1938 100644 --- a/lib/arg.c +++ b/lib/arg.c @@ -22,6 +22,7 @@ #include #include #include +#include /* Built-in parser for default options. */ #define SHORT_ARG_HELP -100 @@ -30,9 +31,9 @@ static const struct grub_arg_option help_options[] = { {"help", SHORT_ARG_HELP, 0, - "display this help and exit", 0, ARG_TYPE_NONE}, + N_("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}, + N_("Display the usage of this command and exit."), 0, ARG_TYPE_NONE}, {0, 0, 0, 0, 0, 0} }; @@ -106,7 +107,7 @@ find_long (const struct grub_arg_option *options, const char *s, int len) static void show_usage (grub_extcmd_t cmd) { - grub_printf ("Usage: %s\n", cmd->cmd->summary); + grub_printf ("%s %s\n", _("Usage:"), _(cmd->cmd->summary)); } void @@ -143,7 +144,7 @@ grub_arg_show_help (grub_extcmd_t cmd) } } - const char *doc = opt->doc; + const char *doc = _(opt->doc); for (;;) { while (spacing-- > 0) @@ -176,7 +177,7 @@ grub_arg_show_help (grub_extcmd_t cmd) } show_usage (cmd); - grub_printf ("%s\n\n", cmd->cmd->description); + grub_printf ("%s\n\n", _(cmd->cmd->description)); if (cmd->options) showargs (cmd->options); showargs (help_options); @@ -274,7 +275,7 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv, if (! opt) { grub_error (GRUB_ERR_BAD_ARGUMENT, - "Unknown argument `-%c'\n", *curshort); + "unknown argument `-%c'", *curshort); goto fail; } @@ -326,7 +327,7 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv, opt = find_long (cmd->options, arg + 2, arglen); if (! opt) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "Unknown argument `%s'\n", arg); + grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown argument `%s'", arg); goto fail; } } @@ -337,7 +338,7 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv, if (! option) { grub_error (GRUB_ERR_BAD_ARGUMENT, - "Missing mandatory option for `%s'\n", opt->longarg); + "missing mandatory option for `%s'", opt->longarg); goto fail; } @@ -359,7 +360,7 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv, if (tail == 0 || tail == option || *tail != '\0' || grub_errno) { grub_error (GRUB_ERR_BAD_ARGUMENT, - "The argument `%s' requires an integer.", + "the argument `%s' requires an integer", arg); goto fail; @@ -382,8 +383,8 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv, if (option) { grub_error (GRUB_ERR_BAD_ARGUMENT, - "A value was assigned to the argument `%s' while it " - "doesn't require an argument\n", arg); + "a value was assigned to the argument `%s' while it " + "doesn't require an argument", arg); goto fail; } 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..620c4bbf3 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; @@ -679,7 +679,7 @@ grub_netbsd_boot (void) + sizeof (struct grub_netbsd_btinfo_mmap_header) + count * sizeof (struct grub_netbsd_btinfo_mmap_entry) > grub_os_area_addr + grub_os_area_size) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, "No memory for boot info."); + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "no memory for boot info"); curarg = mmap = (struct grub_netbsd_btinfo_mmap_header *) kern_end; pm = (struct grub_netbsd_btinfo_mmap_entry *) (mmap + 1); @@ -750,10 +750,10 @@ grub_bsd_load_aout (grub_file_t file) return grub_errno; if (grub_file_read (file, &ah, sizeof (ah)) != sizeof (ah)) - return grub_error (GRUB_ERR_READ_ERROR, "Cannot read the a.out header"); + return grub_error (GRUB_ERR_READ_ERROR, "cannot read the a.out header"); if (grub_aout_get_type (&ah) != AOUT_TYPE_AOUT32) - return grub_error (GRUB_ERR_BAD_OS, "Invalid a.out header"); + return grub_error (GRUB_ERR_BAD_OS, "invalid a.out header"); entry = ah.aout32.a_entry & 0xFFFFFF; @@ -771,7 +771,7 @@ grub_bsd_load_aout (grub_file_t file) } if (load_addr < 0x100000) - return grub_error (GRUB_ERR_BAD_OS, "Load address below 1M"); + return grub_error (GRUB_ERR_BAD_OS, "load address below 1M"); kern_start = load_addr; kern_end = load_addr + ah.aout32.a_text + ah.aout32.a_data; @@ -811,7 +811,7 @@ grub_bsd_elf32_hook (Elf32_Phdr * phdr, grub_addr_t * addr, int *do_load) if ((paddr < grub_os_area_addr) || (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "Address 0x%x is out of range", + return grub_error (GRUB_ERR_OUT_OF_RANGE, "address 0x%x is out of range", paddr); if ((!kern_start) || (paddr < kern_start)) @@ -842,7 +842,7 @@ grub_bsd_elf64_hook (Elf64_Phdr * phdr, grub_addr_t * addr, int *do_load) if ((paddr < grub_os_area_addr) || (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "Address 0x%x is out of range", + return grub_error (GRUB_ERR_OUT_OF_RANGE, "address 0x%x is out of range", paddr); if ((!kern_start) || (paddr < kern_start)) @@ -871,7 +871,7 @@ grub_bsd_load_elf (grub_elf_t elf) is_64bit = 1; if (! grub_cpuid_has_longmode) - return grub_error (GRUB_ERR_BAD_OS, "Your CPU does not implement AMD64 architecture."); + return grub_error (GRUB_ERR_BAD_OS, "your CPU does not implement AMD64 architecture"); /* FreeBSD has 64-bit entry point. */ if (kernel_type == KERNEL_TYPE_FREEBSD) @@ -887,7 +887,7 @@ grub_bsd_load_elf (grub_elf_t elf) return grub_elf64_load (elf, grub_bsd_elf64_hook, 0, 0); } else - return grub_error (GRUB_ERR_BAD_OS, "Invalid elf"); + return grub_error (GRUB_ERR_BAD_OS, "invalid elf"); } static grub_err_t @@ -902,7 +902,7 @@ grub_bsd_load (int argc, char *argv[]) if (argc == 0) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "No kernel specified"); + grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified"); goto fail; } @@ -1024,14 +1024,14 @@ grub_cmd_openbsd (grub_extcmd_t cmd, int argc, char *argv[]) int unit, part; if (*(arg++) != 'w' || *(arg++) != 'd') return grub_error (GRUB_ERR_BAD_ARGUMENT, - "Only device specifications of form " - "wd are supported."); + "only device specifications of form " + "wd are supported"); unit = grub_strtoul (arg, (char **) &arg, 10); if (! (arg && *arg >= 'a' && *arg <= 'z')) return grub_error (GRUB_ERR_BAD_ARGUMENT, - "Only device specifications of form " - "wd are supported."); + "only device specifications of form " + "wd are supported"); part = *arg - 'a'; @@ -1076,15 +1076,15 @@ grub_cmd_freebsd_loadenv (grub_command_t cmd __attribute__ ((unused)), if (kernel_type == KERNEL_TYPE_NONE) return grub_error (GRUB_ERR_BAD_ARGUMENT, - "You need to load the kernel first."); + "you need to load the kernel first"); if (kernel_type != KERNEL_TYPE_FREEBSD) return grub_error (GRUB_ERR_BAD_ARGUMENT, - "Only FreeBSD support environment"); + "only FreeBSD support environment"); if (argc == 0) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "No filename"); + grub_error (GRUB_ERR_BAD_ARGUMENT, "no filename"); goto fail; } @@ -1170,15 +1170,15 @@ grub_cmd_freebsd_module (grub_command_t cmd __attribute__ ((unused)), if (kernel_type == KERNEL_TYPE_NONE) return grub_error (GRUB_ERR_BAD_ARGUMENT, - "You need to load the kernel first."); + "you need to load the kernel first"); if (kernel_type != KERNEL_TYPE_FREEBSD) return grub_error (GRUB_ERR_BAD_ARGUMENT, - "Only FreeBSD support module"); + "only FreeBSD support module"); if (!is_elf_kernel) return grub_error (GRUB_ERR_BAD_ARGUMENT, - "Only ELF kernel support module"); + "only ELF kernel support module"); /* List the current modules if no parameter. */ if (!argc) @@ -1193,7 +1193,7 @@ grub_cmd_freebsd_module (grub_command_t cmd __attribute__ ((unused)), if (kern_end + file->size > grub_os_area_addr + grub_os_area_size) { - grub_error (GRUB_ERR_OUT_OF_RANGE, "Not enough memory for the module"); + grub_error (GRUB_ERR_OUT_OF_RANGE, "not enough memory for the module"); goto fail; } @@ -1236,15 +1236,15 @@ grub_cmd_freebsd_module_elf (grub_command_t cmd __attribute__ ((unused)), if (kernel_type == KERNEL_TYPE_NONE) return grub_error (GRUB_ERR_BAD_ARGUMENT, - "You need to load the kernel first."); + "you need to load the kernel first"); if (kernel_type != KERNEL_TYPE_FREEBSD) return grub_error (GRUB_ERR_BAD_ARGUMENT, - "Only FreeBSD support module"); + "only FreeBSD support module"); if (! is_elf_kernel) return grub_error (GRUB_ERR_BAD_ARGUMENT, - "Only ELF kernel support module"); + "only ELF kernel support module"); /* List the current modules if no parameter. */ if (! argc) diff --git a/loader/i386/bsdXX.c b/loader/i386/bsdXX.c index aedc204b2..4c1c035a9 100644 --- a/loader/i386/bsdXX.c +++ b/loader/i386/bsdXX.c @@ -12,7 +12,7 @@ load (grub_file_t file, void *where, grub_off_t off, grub_size_t size) { if (PTR_TO_UINT32 (where) + size > grub_os_area_addr + grub_os_area_size) return grub_error (GRUB_ERR_OUT_OF_RANGE, - "Not enough memory for the module"); + "not enough memory for the module"); if (grub_file_seek (file, off) == (grub_off_t) -1) return grub_errno; if (grub_file_read (file, where, size) @@ -116,7 +116,7 @@ SUFFIX (grub_freebsd_load_elfmodule_obj) (grub_file_t file, int argc, case SHT_NOBITS: if (curload + s->sh_size > grub_os_area_addr + grub_os_area_size) return grub_error (GRUB_ERR_OUT_OF_RANGE, - "Not enough memory for the module"); + "not enough memory for the module"); grub_memset (UINT_TO_PTR (curload), 0, s->sh_size); break; } @@ -185,7 +185,7 @@ SUFFIX (grub_freebsd_load_elfmodule) (grub_file_t file, int argc, char *argv[], if (module + s->sh_addr + s->sh_size > grub_os_area_addr + grub_os_area_size) return grub_error (GRUB_ERR_OUT_OF_RANGE, - "Not enough memory for the module"); + "not enough memory for the module"); grub_memset (UINT_TO_PTR (module + s->sh_addr), 0, s->sh_size); break; } @@ -259,7 +259,7 @@ SUFFIX (grub_freebsd_load_elf_meta) (grub_file_t file, grub_addr_t *kern_end) if (*kern_end + 4 * sizeof (grub_freebsd_addr_t) + symsize + strsize > grub_os_area_addr + grub_os_area_size) return grub_error (GRUB_ERR_OUT_OF_RANGE, - "Not enough memory for kernel symbols"); + "not enough memory for kernel symbols"); symstart = curload = ALIGN_UP (*kern_end, sizeof (grub_freebsd_addr_t)); *((grub_freebsd_addr_t *) UINT_TO_PTR (curload)) = symsize; diff --git a/loader/i386/efi/linux.c b/loader/i386/efi/linux.c index 8cd4d23f2..d0b218b08 100644 --- a/loader/i386/efi/linux.c +++ b/loader/i386/efi/linux.c @@ -671,7 +671,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), len = 0x400 - sizeof (lh); if (grub_file_read (file, (char *) real_mode_mem + sizeof (lh), len) != len) { - grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file"); goto fail; } @@ -853,7 +853,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), len = prot_size; if (grub_file_read (file, (void *) GRUB_LINUX_BZIMAGE_ADDR, len) != len) - grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file"); if (grub_errno == GRUB_ERR_NONE) { @@ -890,13 +890,13 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), if (argc == 0) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified"); + grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified"); goto fail; } if (! loaded) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first."); + grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first"); goto fail; } @@ -966,7 +966,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), if (grub_file_read (file, initrd_mem, size) != size) { - grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file"); goto fail; } diff --git a/loader/i386/efi/xnu.c b/loader/i386/efi/xnu.c index 236732804..a7ede1960 100644 --- a/loader/i386/efi/xnu.c +++ b/loader/i386/efi/xnu.c @@ -148,10 +148,10 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params) c = grub_efi_locate_protocol (&uga_draw_guid, 0); if (! c) - return grub_error (GRUB_ERR_IO, "Couldn't find UGADraw"); + return grub_error (GRUB_ERR_IO, "couldn't find UGADraw"); if (efi_call_5 (c->get_mode, c, &width, &height, &depth, &rate)) - return grub_error (GRUB_ERR_IO, "Couldn't retrieve video mode"); + return grub_error (GRUB_ERR_IO, "couldn't retrieve video mode"); grub_printf ("Video mode: %ux%u-%u@%u\n", width, height, depth, rate); @@ -163,7 +163,7 @@ grub_xnu_set_video (struct grub_xnu_boot_params *params) grub_efi_set_text_mode (1); if (! ret) - return grub_error (GRUB_ERR_IO, "Can\'t find frame buffer address\n"); + return grub_error (GRUB_ERR_IO, "can\'t find frame buffer address"); grub_printf ("Frame buffer base: 0x%x\n", fb_base); grub_printf ("Video line length: %d\n", line_len); diff --git a/loader/i386/ieee1275/linux.c b/loader/i386/ieee1275/linux.c index 529d1590a..97f9a8216 100644 --- a/loader/i386/ieee1275/linux.c +++ b/loader/i386/ieee1275/linux.c @@ -211,7 +211,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), kernel_size = prot_size; if (grub_file_read (file, kernel_addr, prot_size) != (int) prot_size) - grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file"); if (grub_errno == GRUB_ERR_NONE) grub_loader_set (grub_linux_boot, grub_linux_unload, 1); @@ -242,13 +242,13 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), if (argc == 0) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified"); + grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified"); goto fail; } if (! kernel_addr) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first."); + grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first"); goto fail; } @@ -260,7 +260,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), if (grub_file_read (file, (void *) GRUB_OFW_LINUX_INITRD_ADDR, initrd_size) != (int) initrd_size) { - grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file"); goto fail; } diff --git a/loader/i386/linux.c b/loader/i386/linux.c index 82bfd6b95..805ec7962 100644 --- a/loader/i386/linux.c +++ b/loader/i386/linux.c @@ -673,7 +673,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), len = 0x400 - sizeof (lh); if (grub_file_read (file, (char *) real_mode_mem + sizeof (lh), len) != len) { - grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file"); goto fail; } @@ -862,7 +862,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), len = prot_size; if (grub_file_read (file, (void *) GRUB_LINUX_BZIMAGE_ADDR, len) != len) - grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file"); if (grub_errno == GRUB_ERR_NONE) { @@ -897,13 +897,13 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), if (argc == 0) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified"); + grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified"); goto fail; } if (! loaded) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first."); + grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first"); goto fail; } @@ -951,7 +951,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), if (addr < addr_min) { - grub_error (GRUB_ERR_OUT_OF_RANGE, "The initrd is too big"); + grub_error (GRUB_ERR_OUT_OF_RANGE, "the initrd is too big"); goto fail; } @@ -959,7 +959,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), if (grub_file_read (file, initrd_mem, size) != size) { - grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file"); goto fail; } diff --git a/loader/i386/multiboot.c b/loader/i386/multiboot.c index f5036a2ae..a52b8d5d6 100644 --- a/loader/i386/multiboot.c +++ b/loader/i386/multiboot.c @@ -65,7 +65,7 @@ grub_multiboot_boot (void) { struct grub_relocator32_state state = { - .eax = MULTIBOOT_MAGIC2, + .eax = MULTIBOOT_BOOTLOADER_MAGIC, .ebx = PTR_TO_UINT32 (mbi_dest), .ecx = 0, .edx = 0, @@ -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 @@ -226,21 +226,21 @@ grub_multiboot (int argc, char *argv[]) if (argc == 0) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "No kernel specified"); + grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified"); goto fail; } file = grub_gzfile_open (argv[0], 1); if (! file) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "Couldn't open file"); + grub_error (GRUB_ERR_BAD_ARGUMENT, "couldn't open file"); goto fail; } len = grub_file_read (file, buffer, MULTIBOOT_SEARCH); if (len < 32) { - grub_error (GRUB_ERR_BAD_OS, "File too small"); + grub_error (GRUB_ERR_BAD_OS, "file too small"); goto fail; } @@ -250,21 +250,21 @@ grub_multiboot (int argc, char *argv[]) ((char *) header <= buffer + len - 12) || (header = 0); header = (struct multiboot_header *) ((char *) header + 4)) { - if (header->magic == MULTIBOOT_MAGIC + if (header->magic == MULTIBOOT_HEADER_MAGIC && !(header->magic + header->flags + header->checksum)) break; } if (header == 0) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "No multiboot header found"); + grub_error (GRUB_ERR_BAD_ARGUMENT, "no multiboot header found"); goto fail; } if (header->flags & MULTIBOOT_UNSUPPORTED) { grub_error (GRUB_ERR_UNKNOWN_OS, - "Unsupported flag: 0x%x", header->flags); + "unsupported flag: 0x%x", header->flags); goto fail; } @@ -408,14 +408,14 @@ grub_module (int argc, char *argv[]) if (argc == 0) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified"); + grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified"); goto fail; } if (!mbi) { grub_error (GRUB_ERR_BAD_ARGUMENT, - "You need to load the multiboot kernel first"); + "you need to load the multiboot kernel first"); goto fail; } @@ -430,7 +430,7 @@ grub_module (int argc, char *argv[]) if (grub_file_read (file, module, size) != size) { - grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file"); goto fail; } 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/linux.c b/loader/i386/pc/linux.c index c5279f6ce..9e2543e62 100644 --- a/loader/i386/pc/linux.c +++ b/loader/i386/pc/linux.c @@ -234,7 +234,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), len = real_size + GRUB_DISK_SECTOR_SIZE - sizeof (lh); if (grub_file_read (file, grub_linux_tmp_addr + sizeof (lh), len) != len) { - grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file"); goto fail; } @@ -265,7 +265,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), len = prot_size; if (grub_file_read (file, (void *) GRUB_LINUX_BZIMAGE_ADDR, len) != len) - grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file"); if (grub_errno == GRUB_ERR_NONE) { @@ -299,13 +299,13 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), if (argc == 0) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified"); + grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified"); goto fail; } if (!loaded) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first."); + grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first"); goto fail; } @@ -314,7 +314,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), if (!(lh->header == grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE) && grub_le_to_cpu16 (lh->version) >= 0x0200)) { - grub_error (GRUB_ERR_BAD_OS, "The kernel is too old for initrd."); + grub_error (GRUB_ERR_BAD_OS, "the kernel is too old for initrd"); goto fail; } @@ -357,13 +357,13 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), if (addr < addr_min) { - grub_error (GRUB_ERR_OUT_OF_RANGE, "The initrd is too big"); + grub_error (GRUB_ERR_OUT_OF_RANGE, "the initrd is too big"); goto fail; } if (grub_file_read (file, (void *) addr, size) != size) { - grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file"); goto fail; } diff --git a/loader/i386/pc/multiboot2.c b/loader/i386/pc/multiboot2.c index e2d649613..9bfe5d248 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; @@ -41,14 +42,15 @@ grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr, if ((paddr < grub_os_area_addr) || (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size)) - return grub_error(GRUB_ERR_OUT_OF_RANGE,"Address 0x%x is out of range", + return grub_error(GRUB_ERR_OUT_OF_RANGE,"address 0x%x is out of range", paddr); return GRUB_ERR_NONE; } 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; @@ -62,7 +64,7 @@ grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, UNUSED grub_addr_t *addr, if ((paddr < grub_os_area_addr) || (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size)) - return grub_error (GRUB_ERR_OUT_OF_RANGE, "Address 0x%x is out of range", + return grub_error (GRUB_ERR_OUT_OF_RANGE, "address 0x%x is out of range", paddr); return GRUB_ERR_NONE; @@ -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..f71e2c306 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..8c0bc09ec 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; @@ -50,7 +51,7 @@ grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, UNUSED grub_addr_t *addr, rc = grub_claimmap (phdr->p_paddr, phdr->p_memsz); if (rc) - return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Couldn't claim %x - %x", + return grub_error(GRUB_ERR_OUT_OF_MEMORY, "couldn't claim %x - %x", phdr->p_paddr, phdr->p_paddr + phdr->p_memsz); grub_dprintf ("loader", "Loading segment at 0x%x - 0x%x\n", phdr->p_paddr, @@ -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; @@ -75,7 +77,7 @@ grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, UNUSED grub_addr_t *addr, rc = grub_claimmap (phdr->p_paddr, phdr->p_memsz); if (rc) - return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Couldn't claim 0x%lx - 0x%lx", + return grub_error(GRUB_ERR_OUT_OF_MEMORY, "couldn't claim 0x%lx - 0x%lx", phdr->p_paddr, phdr->p_paddr + phdr->p_memsz); grub_dprintf ("loader", "Loading segment at 0x%lx - 0x%lx\n", @@ -94,7 +96,7 @@ grub_mb2_arch_module_alloc (grub_size_t size, grub_addr_t *addr) rc = grub_ieee1275_claim (0, size, MULTIBOOT2_MOD_ALIGN, addr); if (rc) return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "Firmware couldn't allocate memory (size 0x%lx)", size); + "firmware couldn't allocate memory (size 0x%lx)", size); return GRUB_ERR_NONE; } diff --git a/loader/macho.c b/loader/macho.c index bd460b810..199d6f111 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) { @@ -304,7 +71,7 @@ grub_macho_file (grub_file_t file) != sizeof (filestart)) { grub_error_push (); - grub_error (GRUB_ERR_READ_ERROR, "Cannot read Mach-O header."); + grub_error (GRUB_ERR_READ_ERROR, "cannot read Mach-O header"); goto fail; } @@ -328,7 +95,7 @@ grub_macho_file (grub_file_t file) { grub_free (archs); grub_error_push (); - grub_error (GRUB_ERR_READ_ERROR, "Cannot read Mach-O header."); + grub_error (GRUB_ERR_READ_ERROR, "cannot read Mach-O header"); goto fail; } @@ -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..918ddbb20 --- /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..dbdee9c87 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"); @@ -318,14 +319,14 @@ grub_multiboot2 (int argc, char *argv[]) if (argc == 0) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "No kernel specified"); + grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified"); goto fail; } file = grub_gzfile_open (argv[0], 1); if (! file) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "Couldn't open file"); + grub_error (GRUB_ERR_BAD_ARGUMENT, "couldn't open file"); goto fail; } @@ -336,7 +337,7 @@ grub_multiboot2 (int argc, char *argv[]) len = grub_file_read (file, buffer, MULTIBOOT2_HEADER_SEARCH); if (len < 32) { - grub_error (GRUB_ERR_BAD_OS, "File too small"); + grub_error (GRUB_ERR_BAD_OS, "file too small"); goto fail; } @@ -377,7 +378,7 @@ grub_multiboot2 (int argc, char *argv[]) err = grub_mb2_load_other (file, header); else err = grub_error (GRUB_ERR_BAD_OS, - "Need multiboot 2 header to load non-ELF files."); + "need multiboot 2 header to load non-ELF files"); grub_file_close (file); } @@ -405,20 +406,20 @@ grub_module2 (int argc, char *argv[]) if (argc == 0) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified"); + grub_error (GRUB_ERR_BAD_ARGUMENT, "no module specified"); return; } if (argc == 1) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "No module type specified"); + grub_error (GRUB_ERR_BAD_ARGUMENT, "no module type specified"); return; } if (entry == 0) { grub_error (GRUB_ERR_BAD_ARGUMENT, - "You need to load the multiboot kernel first"); + "you need to load the multiboot kernel first"); return; } @@ -436,7 +437,7 @@ grub_module2 (int argc, char *argv[]) modaddr + modsize); if (grub_file_read (file, (void *) modaddr, modsize) != modsize) { - grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file"); goto out; } diff --git a/loader/multiboot_loader.c b/loader/multiboot_loader.c index 9078d0622..37b33302a 100644 --- a/loader/multiboot_loader.c +++ b/loader/multiboot_loader.c @@ -58,7 +58,7 @@ find_multi_boot1_header (grub_file_t file) ((char *) header <= buffer + len - 12) || (header = 0); header = (struct multiboot_header *) ((char *) header + 4)) { - if (header->magic == MULTIBOOT_MAGIC + if (header->magic == MULTIBOOT_HEADER_MAGIC && !(header->magic + header->flags + header->checksum)) { found_status = 1; @@ -108,14 +108,14 @@ grub_cmd_multiboot_loader (grub_command_t cmd __attribute__ ((unused)), if (argc == 0) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "No kernel specified"); + grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified"); goto fail; } file = grub_gzfile_open (argv[0], 1); if (! file) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "Couldn't open file"); + grub_error (GRUB_ERR_BAD_ARGUMENT, "couldn't open file"); goto fail; } @@ -126,7 +126,7 @@ grub_cmd_multiboot_loader (grub_command_t cmd __attribute__ ((unused)), header_multi_ver_found = 2; else { - grub_error (GRUB_ERR_BAD_OS, "Multiboot header not found"); + grub_error (GRUB_ERR_BAD_OS, "multiboot header not found"); goto fail; } diff --git a/loader/powerpc/ieee1275/linux.c b/loader/powerpc/ieee1275/linux.c index 1056ab9eb..547bd2d9b 100644 --- a/loader/powerpc/ieee1275/linux.c +++ b/loader/powerpc/ieee1275/linux.c @@ -75,10 +75,10 @@ grub_linux_release_mem (void) linux_args = 0; if (linux_addr && grub_ieee1275_release (linux_addr, linux_size)) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Can not release memory"); + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot release memory"); if (initrd_addr && grub_ieee1275_release (initrd_addr, initrd_size)) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Can not release memory"); + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot release memory"); linux_addr = 0; initrd_addr = 0; @@ -128,7 +128,7 @@ grub_linux_load32 (grub_elf_t elf) break; } if (found_addr == -1) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Could not claim memory."); + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't claim memory"); /* Now load the segments into the area we claimed. */ auto grub_err_t offset_phdr (Elf32_Phdr *phdr, grub_addr_t *addr, int *do_load); @@ -178,7 +178,7 @@ grub_linux_load64 (grub_elf_t elf) break; } if (found_addr == -1) - return grub_error (GRUB_ERR_OUT_OF_MEMORY, "Could not claim memory."); + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't claim memory"); /* Now load the segments into the area we claimed. */ auto grub_err_t offset_phdr (Elf64_Phdr *phdr, grub_addr_t *addr, int *do_load); @@ -222,7 +222,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), if (elf->ehdr.ehdr32.e_type != ET_EXEC) { grub_error (GRUB_ERR_UNKNOWN_OS, - "This ELF file is not of the right type\n"); + "this ELF file is not of the right type"); goto out; } @@ -236,7 +236,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_linux_load64 (elf); else { - grub_error (GRUB_ERR_BAD_FILE_TYPE, "Unknown ELF class"); + grub_error (GRUB_ERR_BAD_FILE_TYPE, "unknown ELF class"); goto out; } @@ -297,7 +297,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), if (!loaded) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first."); + grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first"); goto fail; } @@ -321,7 +321,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), if (found_addr == -1) { - grub_error (GRUB_ERR_OUT_OF_MEMORY, "Can not claim memory"); + grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot claim memory"); goto fail; } @@ -330,7 +330,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), if (grub_file_read (file, (void *) addr, size) != size) { grub_ieee1275_release (addr, size); - grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file"); goto fail; } diff --git a/loader/sparc64/ieee1275/linux.c b/loader/sparc64/ieee1275/linux.c index df420d8a0..820110847 100644 --- a/loader/sparc64/ieee1275/linux.c +++ b/loader/sparc64/ieee1275/linux.c @@ -256,12 +256,12 @@ grub_linux_load64 (grub_elf_t elf) paddr = alloc_phys (linux_size + off); if (paddr == (grub_addr_t) -1) return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "Could not allocate physical memory."); + "couldn't allocate physical memory"); ret = grub_ieee1275_map_physical (paddr, linux_addr - off, linux_size + off, IEEE1275_MAP_DEFAULT); if (ret) return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "Could not map physical memory."); + "couldn't map physical memory"); grub_dprintf ("loader", "Loading linux at vaddr 0x%lx, paddr 0x%lx, size 0x%lx\n", linux_addr, paddr, linux_size); @@ -317,7 +317,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), if (elf->ehdr.ehdr32.e_type != ET_EXEC) { grub_error (GRUB_ERR_UNKNOWN_OS, - "This ELF file is not of the right type\n"); + "this ELF file is not of the right type"); goto out; } @@ -328,7 +328,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_linux_load64 (elf); else { - grub_error (GRUB_ERR_BAD_FILE_TYPE, "Unknown ELF class"); + grub_error (GRUB_ERR_BAD_FILE_TYPE, "unknown ELF class"); goto out; } @@ -390,7 +390,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), if (!loaded) { - grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first."); + grub_error (GRUB_ERR_BAD_ARGUMENT, "you need to load the kernel first"); goto fail; } @@ -405,14 +405,14 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), if (paddr == (grub_addr_t) -1) { grub_error (GRUB_ERR_OUT_OF_MEMORY, - "Could not allocate physical memory."); + "couldn't allocate physical memory"); goto fail; } ret = grub_ieee1275_map_physical (paddr, addr, size, IEEE1275_MAP_DEFAULT); if (ret) { grub_error (GRUB_ERR_OUT_OF_MEMORY, - "Could not map physical memory."); + "couldn't map physical memory"); goto fail; } @@ -421,7 +421,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), if (grub_file_read (file, (void *) addr, size) != size) { - grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file"); + grub_error (GRUB_ERR_FILE_READ_ERROR, "couldn't read file"); goto fail; } diff --git a/loader/xnu.c b/loader/xnu.c index cc6d55ae2..85d2882b6 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"); @@ -511,9 +654,12 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) if (macho) grub_macho_close (macho); return grub_error (GRUB_ERR_BAD_OS, - "Extension doesn't contain suitable architecture"); + "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; @@ -569,14 +719,22 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile) { grub_file_close (infoplist); grub_error_push (); - return grub_error (GRUB_ERR_BAD_OS, "Couldn't read file %s: ", + return grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s: ", infoplistname); } 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); @@ -605,7 +763,7 @@ grub_cmd_xnu_mkext (grub_command_t cmd __attribute__ ((unused)), file = grub_gzfile_open (args[0], 1); if (! file) return grub_error (GRUB_ERR_FILE_NOT_FOUND, - "Couldn't load driver package"); + "couldn't load driver package"); /* Sometimes caches are fat binary. Errgh. */ if (grub_file_read (file, &head, sizeof (head)) @@ -615,7 +773,7 @@ grub_cmd_xnu_mkext (grub_command_t cmd __attribute__ ((unused)), can hardly imagine a valid package shorter than 20 bytes. */ grub_file_close (file); grub_error_push (); - return grub_error (GRUB_ERR_BAD_OS, "Couldn't read file %s", args[0]); + return grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", args[0]); } /* Find the corresponding architecture. */ @@ -628,7 +786,7 @@ grub_cmd_xnu_mkext (grub_command_t cmd __attribute__ ((unused)), grub_file_close (file); grub_error_push (); return grub_error (GRUB_ERR_OUT_OF_MEMORY, - "Couldn't read file %s", args[0]); + "couldn't read file %s", args[0]); } if (grub_file_read (file, archs, @@ -637,11 +795,17 @@ grub_cmd_xnu_mkext (grub_command_t cmd __attribute__ ((unused)), { grub_free (archs); grub_error_push (); - return grub_error (GRUB_ERR_READ_ERROR, "Cannot read fat header."); + return grub_error (GRUB_ERR_READ_ERROR, "cannot read fat header"); } 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); @@ -684,7 +848,7 @@ grub_cmd_xnu_mkext (grub_command_t cmd __attribute__ ((unused)), { grub_file_close (file); grub_error_push (); - return grub_error (GRUB_ERR_BAD_OS, "Couldn't read file %s", args[0]); + return grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", args[0]); } grub_file_close (file); @@ -711,7 +875,7 @@ grub_cmd_xnu_ramdisk (grub_command_t cmd __attribute__ ((unused)), file = grub_gzfile_open (args[0], 1); if (! file) return grub_error (GRUB_ERR_FILE_NOT_FOUND, - "Couldn't load ramdisk"); + "couldn't load ramdisk"); err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE); if (err) @@ -727,140 +891,11 @@ grub_cmd_xnu_ramdisk (grub_command_t cmd __attribute__ ((unused)), { grub_file_close (file); grub_error_push (); - return grub_error (GRUB_ERR_BAD_OS, "Couldn't read file %s", args[0]); + return grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", args[0]); } return grub_xnu_register_memory ("RAMDisk", 0, loadto, size); } -/* 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 @@ -882,7 +917,7 @@ grub_xnu_check_os_bundle_required (char *plistname, char *osbundlereq, { grub_file_close (file); grub_error_push (); - grub_error (GRUB_ERR_BAD_OS, "Couldn't read file %s", plistname); + grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", plistname); return 0; } @@ -892,14 +927,14 @@ grub_xnu_check_os_bundle_required (char *plistname, char *osbundlereq, { grub_file_close (file); grub_error_push (); - grub_error (GRUB_ERR_OUT_OF_MEMORY, "Couldn't read file %s", plistname); + grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't read file %s", plistname); return 0; } if (grub_file_read (file, buf, size) != (grub_ssize_t) (size)) { grub_file_close (file); grub_error_push (); - grub_error (GRUB_ERR_BAD_OS, "Couldn't read file %s", plistname); + grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", plistname); return 0; } grub_file_close (file); @@ -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/loader/xnu_resume.c b/loader/xnu_resume.c index 83c2c3cd1..e6620e7b7 100644 --- a/loader/xnu_resume.c +++ b/loader/xnu_resume.c @@ -109,7 +109,7 @@ grub_xnu_resume (char *imagename) != (grub_ssize_t) codesize) { grub_file_close (file); - return grub_error (GRUB_ERR_READ_ERROR, "Cannot read resume image."); + return grub_error (GRUB_ERR_READ_ERROR, "cannot read resume image"); } /* Read image. */ @@ -119,7 +119,7 @@ grub_xnu_resume (char *imagename) != (grub_ssize_t) hibhead.image_size) { grub_file_close (file); - return grub_error (GRUB_ERR_READ_ERROR, "Cannot read resume image."); + return grub_error (GRUB_ERR_READ_ERROR, "cannot read resume image"); } grub_file_close (file); diff --git a/mmap/i386/pc/mmap.c b/mmap/i386/pc/mmap.c index 0e2dfe6a6..7d5a43fec 100644 --- a/mmap/i386/pc/mmap.c +++ b/mmap/i386/pc/mmap.c @@ -179,7 +179,7 @@ malloc_hook (void) if (! hooktarget) { slots_available = 0; - return grub_error (GRUB_ERR_OUT_OF_MEMORY, "No space for mmap hook"); + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "no space for mmap hook"); } return GRUB_ERR_NONE; } 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/dyncmd.c b/normal/dyncmd.c index dc530b07b..04f1945dc 100644 --- a/normal/dyncmd.c +++ b/normal/dyncmd.c @@ -23,6 +23,7 @@ #include #include #include +#include static grub_err_t grub_dyncmd_dispatcher (struct grub_command *cmd, @@ -132,7 +133,7 @@ read_command_list (void) cmd = grub_register_command_prio (name, grub_dyncmd_dispatcher, - 0, "not loaded", prio); + 0, N_("not loaded"), prio); if (! cmd) { grub_free (name); 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/menu_viewer.c b/normal/menu_viewer.c index 1bd271a21..f870ccd53 100644 --- a/normal/menu_viewer.c +++ b/normal/menu_viewer.c @@ -58,7 +58,7 @@ grub_menu_viewer_show_menu (grub_menu_t menu, int nested) grub_menu_viewer_t cur = get_current_menu_viewer (); grub_err_t err1, err2; if (!cur) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "No menu viewer available."); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no menu viewer available"); while (1) { 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/partmap/acorn.c b/partmap/acorn.c index e005975c0..076d998f8 100644 --- a/partmap/acorn.c +++ b/partmap/acorn.c @@ -85,7 +85,7 @@ acorn_partition_map_find (grub_disk_t disk, struct linux_part *m, fail: return grub_error (GRUB_ERR_BAD_PART_TABLE, - "Linux/ADFS partition map not found."); + "Linux/ADFS partition map not found"); } diff --git a/partmap/amiga.c b/partmap/amiga.c index dce9f4f1f..e8ba9181c 100644 --- a/partmap/amiga.c +++ b/partmap/amiga.c @@ -102,7 +102,7 @@ amiga_partition_map_iterate (grub_disk_t disk, if (next == -1) return grub_error (GRUB_ERR_BAD_PART_TABLE, - "Amiga partition map not found."); + "Amiga partition map not found"); /* The end of the partition list is marked using "-1". */ while (next != -1) diff --git a/partmap/apple.c b/partmap/apple.c index 4dea55a32..765912672 100644 --- a/partmap/apple.c +++ b/partmap/apple.c @@ -176,7 +176,7 @@ apple_partition_map_iterate (grub_disk_t disk, fail: return grub_error (GRUB_ERR_BAD_PART_TABLE, - "Apple partition map not found."); + "Apple partition map not found"); } diff --git a/po/POTFILES b/po/POTFILES index 28623a096..b36f7bbf2 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -1,4 +1,13 @@ # List of files which contain translatable strings. +commands/i386/pc/play.c +commands/loadenv.c +commands/search.c +commands/help.c + +lib/arg.c + +normal/dyncmd.c + util/grub-mkrawimage.c util/i386/pc/grub-setup.c @@ -11,5 +20,9 @@ util/mkisofs/rock.c util/mkisofs/tree.c util/mkisofs/write.c +normal/auth.c +normal/color.c +normal/main.c normal/menu_entry.c normal/menu_text.c +normal/misc.c diff --git a/script/lexer.c b/script/lexer.c index a30e3c005..5bcdf628b 100644 --- a/script/lexer.c +++ b/script/lexer.c @@ -389,7 +389,7 @@ grub_script_yylex (union YYSTYPE *yylval, struct grub_parser_param *parsestate) { /* There is either text or a variable name. In the case you arrive here there is a serious problem with the lexer. */ - grub_error (GRUB_ERR_BAD_ARGUMENT, "Internal error\n"); + grub_error (GRUB_ERR_BAD_ARGUMENT, "internal error"); return 0; } } diff --git a/term/at_keyboard.c b/term/at_keyboard.c index 9171430f4..09ee9191d 100644 --- a/term/at_keyboard.c +++ b/term/at_keyboard.c @@ -33,6 +33,13 @@ static int pending_key = -1; #define KEYBOARD_STATUS_CTRL_L (1 << 4) #define KEYBOARD_STATUS_CTRL_R (1 << 5) #define KEYBOARD_STATUS_CAPS_LOCK (1 << 6) +#define KEYBOARD_STATUS_NUM_LOCK (1 << 7) + +static grub_uint8_t led_status; + +#define KEYBOARD_LED_SCROLL (1 << 0) +#define KEYBOARD_LED_NUM (1 << 1) +#define KEYBOARD_LED_CAPS (1 << 2) static char keyboard_map[128] = { @@ -66,9 +73,15 @@ static char keyboard_map_shift[128] = static grub_uint8_t grub_keyboard_controller_orig; static void -grub_keyboard_controller_write (grub_uint8_t c) +keyboard_controller_wait_untill_ready () { while (! KEYBOARD_COMMAND_ISREADY (grub_inb (KEYBOARD_REG_STATUS))); +} + +static void +grub_keyboard_controller_write (grub_uint8_t c) +{ + keyboard_controller_wait_untill_ready (); grub_outb (KEYBOARD_COMMAND_WRITE, KEYBOARD_REG_STATUS); grub_outb (c, KEYBOARD_REG_DATA); } @@ -76,11 +89,20 @@ grub_keyboard_controller_write (grub_uint8_t c) static grub_uint8_t grub_keyboard_controller_read (void) { - while (! KEYBOARD_COMMAND_ISREADY (grub_inb (KEYBOARD_REG_STATUS))); + keyboard_controller_wait_untill_ready (); grub_outb (KEYBOARD_COMMAND_READ, KEYBOARD_REG_STATUS); return grub_inb (KEYBOARD_REG_DATA); } +static void +keyboard_controller_led (grub_uint8_t led_status) +{ + keyboard_controller_wait_untill_ready (); + grub_outb (0xed, KEYBOARD_REG_DATA); + keyboard_controller_wait_untill_ready (); + grub_outb (led_status & 0x7, KEYBOARD_REG_DATA); +} + /* FIXME: This should become an interrupt service routine. For now it's just used to catch events from control keys. */ static void @@ -159,14 +181,37 @@ grub_at_keyboard_getkey_noblock (void) switch (code) { case CAPS_LOCK: - at_keyboard_status ^= KEYBOARD_STATUS_CAPS_LOCK; /* Caps lock sends scan code twice. Get the second one and discard it. */ while (grub_keyboard_getkey () == -1); + + at_keyboard_status ^= KEYBOARD_STATUS_CAPS_LOCK; + led_status ^= KEYBOARD_LED_CAPS; + keyboard_controller_led (led_status); + #ifdef DEBUG_AT_KEYBOARD grub_dprintf ("atkeyb", "caps_lock = %d\n", !!(at_keyboard_status & KEYBOARD_STATUS_CAPS_LOCK)); #endif key = -1; break; + case NUM_LOCK: + /* Num lock sends scan code twice. Get the second one and discard it. */ + while (grub_keyboard_getkey () == -1); + + at_keyboard_status ^= KEYBOARD_STATUS_NUM_LOCK; + led_status ^= KEYBOARD_LED_NUM; + keyboard_controller_led (led_status); + +#ifdef DEBUG_AT_KEYBOARD + grub_dprintf ("atkeyb", "num_lock = %d\n", !!(at_keyboard_status & KEYBOARD_STATUS_NUM_LOCK)); +#endif + key = -1; + break; + case SCROLL_LOCK: + /* For scroll lock we don't keep track of status. Only update its led. */ + led_status ^= KEYBOARD_LED_SCROLL; + keyboard_controller_led (led_status); + key = -1; + break; default: if (at_keyboard_status & (KEYBOARD_STATUS_CTRL_L | KEYBOARD_STATUS_CTRL_R)) key = keyboard_map[code] - 'a' + 1; diff --git a/term/gfxterm.c b/term/gfxterm.c index 972c7236d..c2ee2d995 100644 --- a/term/gfxterm.c +++ b/term/gfxterm.c @@ -190,7 +190,7 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y, virtual_screen.font = grub_font_get (font_name); if (!virtual_screen.font) return grub_error (GRUB_ERR_BAD_FONT, - "No font loaded."); + "no font loaded"); virtual_screen.width = width; virtual_screen.height = height; virtual_screen.offset_x = x; diff --git a/term/i386/pc/vga.c b/term/i386/pc/vga.c index 9deb6a6d7..402b30fe6 100644 --- a/term/i386/pc/vga.c +++ b/term/i386/pc/vga.c @@ -163,7 +163,7 @@ grub_vga_mod_init (void) set_start_address (PAGE_OFFSET (page)); font = grub_font_get (""); /* Choose any font, for now. */ if (!font) - return grub_error (GRUB_ERR_BAD_FONT, "No font loaded."); + return grub_error (GRUB_ERR_BAD_FONT, "no font loaded"); return GRUB_ERR_NONE; } diff --git a/term/ieee1275/ofconsole.c b/term/ieee1275/ofconsole.c index c61e16eb7..fbed9eca1 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 @@ -345,7 +346,7 @@ grub_ofconsole_init_input (void) if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, "stdin", &stdin_ihandle, sizeof stdin_ihandle, &actual) || actual != sizeof stdin_ihandle) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Cannot find stdin"); + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot find stdin"); return 0; } @@ -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 @@ -365,12 +365,13 @@ grub_ofconsole_init_output (void) if (grub_ieee1275_get_integer_property (grub_ieee1275_chosen, "stdout", &stdout_ihandle, sizeof stdout_ihandle, &actual) || actual != sizeof stdout_ihandle) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Cannot find stdout"); + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "cannot find stdout"); /* 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/term/serial.c b/term/serial.c index c9d12e4e7..44e230311 100644 --- a/term/serial.c +++ b/term/serial.c @@ -501,7 +501,7 @@ grub_cmd_serial (grub_extcmd_t cmd, unit = grub_strtoul (state[0].arg, 0, 0); serial_settings.port = serial_hw_get_port (unit); if (!serial_settings.port) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad unit number."); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad unit number"); } if (state[1].set) diff --git a/term/terminfo.c b/term/terminfo.c index 80ae9b100..e5328d06b 100644 --- a/term/terminfo.c +++ b/term/terminfo.c @@ -103,7 +103,7 @@ grub_terminfo_set_current (const char *str) return grub_errno; } - return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminfo type."); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminfo type"); } /* Wrapper for grub_putchar to write strings. */ @@ -168,7 +168,7 @@ grub_cmd_terminfo (grub_command_t cmd __attribute__ ((unused)), return GRUB_ERR_NONE; } else if (argc != 1) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many parameters."); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many parameters"); else return grub_terminfo_set_current (args[0]); } diff --git a/util/getroot.c b/util/getroot.c index c6c229967..22ad7e967 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -483,12 +483,12 @@ grub_util_is_dmraid (const char *os_dev) return 1; else if (! strncmp (os_dev, "/dev/mapper/sil_", 16)) return 1; - + return 0; } int -grub_util_get_dev_abstraction (const char *os_dev UNUSED) +grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused))) { #ifdef __linux__ /* Check for LVM. */ diff --git a/util/grub-install.in b/util/grub-install.in index 494ac6bc3..bc7035a2d 100644 --- a/util/grub-install.in +++ b/util/grub-install.in @@ -29,6 +29,7 @@ PACKAGE_TARNAME=@PACKAGE_TARNAME@ PACKAGE_VERSION=@PACKAGE_VERSION@ target_cpu=@target_cpu@ platform=@platform@ +host_os=@host_os@ font=@datadir@/@PACKAGE_TARNAME@/ascii.pf2 pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` 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-mkrawimage.c b/util/grub-mkrawimage.c index 58b30f5be..8186c8601 100644 --- a/util/grub-mkrawimage.c +++ b/util/grub-mkrawimage.c @@ -236,19 +236,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); - + *((grub_uint16_t *) (boot_img + GRUB_DISK_SECTOR_SIZE - GRUB_BOOT_MACHINE_LIST_SIZE + 8)) = grub_host_to_target16 (num); - + grub_util_write_image (boot_img, boot_size, out); free (boot_img); free (boot_path); @@ -357,13 +357,13 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], ehdr->e_shentsize = grub_host_to_target16 (0); ehdr->e_shnum = grub_host_to_target16 (0); ehdr->e_shstrndx = grub_host_to_target16 (0); - + ehdr->e_ehsize = grub_host_to_target16 (sizeof (*ehdr)); - + phdr->p_type = grub_host_to_target32 (PT_LOAD); phdr->p_offset = grub_host_to_target32 (sizeof (*ehdr) + sizeof (*phdr)); phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); - + target_addr = ALIGN_UP (GRUB_KERNEL_MACHINE_LINK_ADDR + kernel_size + total_module_size, 32); ehdr->e_entry = grub_host_to_target32 (target_addr); diff --git a/util/grub-mkrelpath.c b/util/grub-mkrelpath.c index a20109628..956e52ed7 100644 --- a/util/grub-mkrelpath.c +++ b/util/grub-mkrelpath.c @@ -27,6 +27,7 @@ static struct option options[] = { {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, + {0, 0, 0, 0}, }; static void diff --git a/util/grub-mkrescue.in b/util/grub-mkrescue.in index 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-probe.c b/util/grub-probe.c index 6d421445c..ebf5142d4 100644 --- a/util/grub-probe.c +++ b/util/grub-probe.c @@ -123,7 +123,7 @@ probe (const char *path, char *device_name) device_name = grub_guess_root_device (path); if (! device_name) - grub_util_error ("cannot find a device for %s.\n", path); + grub_util_error ("cannot find a device for %s (is /dev mounted?).\n", path); if (print == PRINT_DEVICE) { @@ -259,7 +259,7 @@ probe (const char *path, char *device_name) grub_util_info ("reading %s via GRUB facilities", grub_path); file = grub_file_open (grub_path); if (! file) - grub_util_error ("can not open %s via GRUB facilities", grub_path); + grub_util_error ("cannot open %s via GRUB facilities", grub_path); filebuf_via_grub = xmalloc (file->size); grub_file_read (file, filebuf_via_grub, file->size); 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/hostdisk.c b/util/hostdisk.c index 11caaf407..c94f4237e 100644 --- a/util/hostdisk.c +++ b/util/hostdisk.c @@ -348,7 +348,8 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) return -1; } - /* Make the buffer cache consistent with the physical disk. */ + /* Flush the buffer cache to the physical disk. + XXX: This also empties the buffer cache. */ ioctl (fd, BLKFLSBUF, 0); if (is_partition) diff --git a/util/i386/efi/grub-dumpdevtree b/util/i386/efi/grub-dumpdevtree index bc13e3c35..25aa35e23 100644 --- a/util/i386/efi/grub-dumpdevtree +++ b/util/i386/efi/grub-dumpdevtree @@ -15,11 +15,8 @@ # You should have received a copy of the GNU General Public License # along with GRUB. If not, see . -hexify() -{ - echo -n "$@" | od -A n -t x1 - | sed -e 's/ //g' | tr '\n' '\0' -} +if [ x$1 == x ]; then + echo "Filename required". +fi -echo "`hexify efi`{ `hexify device-properties`:" -ioreg -lw0 -p IODeviceTree -n efi -r -x |grep device-properties | sed 's/.*.*//;' -echo ";}" +ioreg -lw0 -p IODeviceTree -n efi -r -x |grep device-properties | sed 's/.*.*//;' | xxd -r -p > $1 diff --git a/util/i386/efi/grub-install.in b/util/i386/efi/grub-install.in index a5f97e346..e0e0f2717 100644 --- a/util/i386/efi/grub-install.in +++ b/util/i386/efi/grub-install.in @@ -29,6 +29,7 @@ PACKAGE_TARNAME=@PACKAGE_TARNAME@ PACKAGE_VERSION=@PACKAGE_VERSION@ target_cpu=@target_cpu@ platform=@platform@ +host_os=@host_os@ pkglibdir=${libdir}/`echo ${PACKAGE_TARNAME}/${target_cpu}-${platform} | sed ${transform}` grub_mkimage=${bindir}/`echo grub-mkimage | sed ${transform}` diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c index 1c7e8452f..c2b9b9268 100644 --- a/util/i386/pc/grub-setup.c +++ b/util/i386/pc/grub-setup.c @@ -356,8 +356,12 @@ setup (const char *dir, goto unable_to_embed; } - grub_partition_iterate (dest_dev->disk, (strcmp (dest_partmap, "part_msdos") ? - find_usable_region_gpt : find_usable_region_msdos)); + if (strcmp (dest_partmap, "part_msdos") == 0) + grub_partition_iterate (dest_dev->disk, find_usable_region_msdos); + else if (strcmp (dest_partmap, "part_gpt") == 0) + grub_partition_iterate (dest_dev->disk, find_usable_region_gpt); + else + grub_util_error (_("No DOS-style partitions found")); if (embed_region.end == embed_region.start) { diff --git a/util/ieee1275/devicemap.c b/util/ieee1275/devicemap.c index bddfc17e7..19ab746ef 100644 --- a/util/ieee1275/devicemap.c +++ b/util/ieee1275/devicemap.c @@ -35,8 +35,10 @@ escape_of_path (const char *orig_path) } void -grub_util_emit_devicemap_entry (FILE *fp, char *name, int is_floppy UNUSED, - int *num_fd UNUSED, int *num_hd UNUSED) +grub_util_emit_devicemap_entry (FILE *fp, char *name, + int is_floppy __attribute__((unused)), + int *num_fd __attribute__((unused)), + int *num_hd __attribute__((unused))) { const char *orig_path = grub_util_devname_to_ofpath (name); char *ofpath = escape_of_path (orig_path); diff --git a/util/ieee1275/ofpath.c b/util/ieee1275/ofpath.c index 7b464bf09..e90488fc3 100644 --- a/util/ieee1275/ofpath.c +++ b/util/ieee1275/ofpath.c @@ -39,7 +39,6 @@ #include #ifdef OFPATH_STANDALONE -#define UNUSED __attribute__((unused)) #define xmalloc malloc void grub_util_error (const char *fmt, ...) @@ -199,8 +198,10 @@ get_basename(char *p) static void of_path_of_vdisk(char *of_path, - const char *devname UNUSED, const char *device, - const char *devnode UNUSED, const char *devicenode) + const char *devname __attribute__((unused)), + const char *device, + const char *devnode __attribute__((unused)), + const char *devicenode) { char *sysfs_path, *p; int devno, junk; @@ -217,8 +218,9 @@ of_path_of_vdisk(char *of_path, static void of_path_of_ide(char *of_path, - const char *devname UNUSED, const char *device, - const char *devnode UNUSED, const char *devicenode) + const char *devname __attribute__((unused)), const char *device, + const char *devnode __attribute__((unused)), + const char *devicenode) { char *sysfs_path, *p; int chan, devno; @@ -299,8 +301,9 @@ check_sas (char *sysfs_path, int *tgt) static void of_path_of_scsi(char *of_path, - const char *devname UNUSED, const char *device, - const char *devnode UNUSED, const char *devicenode) + const char *devname __attribute__((unused)), const char *device, + const char *devnode __attribute__((unused)), + const char *devicenode) { const char *p, *digit_string, *disk_name; int host, bus, tgt, lun; diff --git a/util/misc.c b/util/misc.c index 5896da0c8..6aa92fb64 100644 --- a/util/misc.c +++ b/util/misc.c @@ -504,7 +504,7 @@ make_system_path_relative_to_its_root (const char *path) free (p); if (stat (buf, &st) < 0) - grub_util_error ("can not stat %s: %s", buf, strerror (errno)); + grub_util_error ("cannot stat %s: %s", buf, strerror (errno)); buf2 = strdup (buf); num = st.st_dev; @@ -523,7 +523,7 @@ make_system_path_relative_to_its_root (const char *path) *++p = 0; if (stat (buf, &st) < 0) - grub_util_error ("can not stat %s: %s", buf, strerror (errno)); + grub_util_error ("cannot stat %s: %s", buf, strerror (errno)); /* buf is another filesystem; we found it. */ if (st.st_dev != num) 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..896e2833b 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,48 @@ 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); + if (fgetc (fp) != EOF) + error (1, 0, _("%s is too big for embed area"), boot_image_embed); } - 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/bitmap.c b/video/bitmap.c index 7b135a5dc..2ea640728 100644 --- a/video/bitmap.c +++ b/video/bitmap.c @@ -58,12 +58,12 @@ grub_video_bitmap_create (struct grub_video_bitmap **bitmap, unsigned int size; if (!bitmap) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid argument."); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument"); *bitmap = 0; if (width == 0 || height == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid argument."); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument"); *bitmap = (struct grub_video_bitmap *)grub_malloc (sizeof (struct grub_video_bitmap)); if (! *bitmap) @@ -129,7 +129,7 @@ grub_video_bitmap_create (struct grub_video_bitmap **bitmap, *bitmap = 0; return grub_error (GRUB_ERR_BAD_ARGUMENT, - "Unsupported bitmap format"); + "unsupported bitmap format"); } mode_info->pitch = width * mode_info->bytes_per_pixel; @@ -188,7 +188,7 @@ grub_video_bitmap_load (struct grub_video_bitmap **bitmap, grub_video_bitmap_reader_t reader = bitmap_readers_list; if (!bitmap) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid argument."); + return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument"); *bitmap = 0; diff --git a/video/efi_gop.c b/video/efi_gop.c index e2eb2f7ae..30863c1ed 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 @@ -137,7 +137,7 @@ grub_video_gop_fill_mode_info (struct grub_efi_gop_mode_info *in, out->bpp = grub_video_gop_get_bpp (in); out->bytes_per_pixel = out->bpp >> 3; if (!out->bpp) - return grub_error (GRUB_ERR_IO, "Unsupported video mode"); + return grub_error (GRUB_ERR_IO, "unsupported video mode"); out->pitch = in->pixels_per_scanline * out->bytes_per_pixel; switch (in->pixel_format) @@ -176,7 +176,7 @@ grub_video_gop_fill_mode_info (struct grub_efi_gop_mode_info *in, break; default: - return grub_error (GRUB_ERR_IO, "Unsupported video mode"); + return grub_error (GRUB_ERR_IO, "unsupported video mode"); } out->blit_format = grub_video_get_blit_format (out); @@ -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; } @@ -266,7 +266,7 @@ grub_video_gop_setup (unsigned int width, unsigned int height, if (!found) { grub_dprintf ("video", "GOP: no mode found\n"); - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching mode found."); + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching mode found"); } if (best_mode != gop->mode->mode) @@ -293,8 +293,8 @@ grub_video_gop_setup (unsigned int width, unsigned int height, grub_dprintf ("video", "GOP: initialising FB @ %p %dx%dx%d\n", framebuffer.ptr, framebuffer.mode_info.width, framebuffer.mode_info.height, framebuffer.mode_info.bpp); - - err = grub_video_fb_create_render_target_from_pointer + + err = grub_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr); if (err) @@ -302,15 +302,15 @@ grub_video_gop_setup (unsigned int width, unsigned int height, grub_dprintf ("video", "GOP: Couldn't create FB target\n"); return err; } - + err = grub_video_fb_set_active_render_target (framebuffer.render_target); - + if (err) { grub_dprintf ("video", "GOP: Couldn't set FB target\n"); return err; } - + err = grub_video_fb_set_palette (0, GRUB_VIDEO_FBSTD_NUMCOLORS, grub_video_fbstd_colors); @@ -318,7 +318,7 @@ grub_video_gop_setup (unsigned int width, unsigned int height, grub_dprintf ("video", "GOP: Couldn't set palette\n"); else grub_dprintf ("video", "GOP: Success\n"); - + return err; } diff --git a/video/efi_uga.c b/video/efi_uga.c index 9bca64306..12ca35cde 100644 --- a/video/efi_uga.c +++ b/video/efi_uga.c @@ -266,7 +266,7 @@ grub_video_uga_setup (unsigned int width, unsigned int height, return err; } - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching mode found."); + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching mode found"); } static grub_err_t diff --git a/video/fb/video_fb.c b/video/fb/video_fb.c index 5f2917da6..5532a343c 100644 --- a/video/fb/video_fb.c +++ b/video/fb/video_fb.c @@ -1048,7 +1048,7 @@ grub_video_fb_create_render_target (struct grub_video_fbrender_target **result, || (width == 0) || (height == 0)) return grub_error (GRUB_ERR_BAD_ARGUMENT, - "invalid argument given."); + "invalid argument given"); /* Allocate memory for render target. */ target = grub_malloc (sizeof (struct grub_video_fbrender_target)); @@ -1168,7 +1168,7 @@ grub_video_fb_set_active_render_target (struct grub_video_fbrender_target *targe { if (! target->data) return grub_error (GRUB_ERR_BAD_ARGUMENT, - "invalid render target given."); + "invalid render target given"); render_target = target; diff --git a/video/i386/pc/vbe.c b/video/i386/pc/vbe.c index a285b26ba..17d9b3282 100644 --- a/video/i386/pc/vbe.c +++ b/video/i386/pc/vbe.c @@ -33,6 +33,9 @@ static int vbe_detected = -1; static struct grub_vbe_info_block controller_info; static struct grub_vbe_mode_info_block active_vbe_mode_info; +/* Track last mode to support cards which fail on get_mode. */ +static grub_uint32_t last_set_mode = 3; + static struct { struct grub_video_mode_info mode_info; @@ -160,6 +163,7 @@ grub_vbe_set_video_mode (grub_uint32_t vbe_mode, status = grub_vbe_bios_set_mode (vbe_mode, 0); if (status != GRUB_VBE_STATUS_OK) return grub_error (GRUB_ERR_BAD_DEVICE, "cannot set VBE mode %x", vbe_mode); + last_set_mode = vbe_mode; /* Save information for later usage. */ framebuffer.active_vbe_mode = vbe_mode; @@ -203,6 +207,7 @@ grub_vbe_set_video_mode (grub_uint32_t vbe_mode, case 8: framebuffer.bytes_per_pixel = 1; break; default: grub_vbe_bios_set_mode (old_vbe_mode, 0); + last_set_mode = old_vbe_mode; return grub_error (GRUB_ERR_BAD_DEVICE, "cannot set VBE mode %x", vbe_mode); @@ -256,8 +261,9 @@ grub_vbe_get_video_mode (grub_uint32_t *mode) /* Try to query current mode from VESA BIOS. */ status = grub_vbe_bios_get_mode (mode); + /* XXX: ATI cards don't support get_mode. */ if (status != GRUB_VBE_STATUS_OK) - return grub_error (GRUB_ERR_BAD_DEVICE, "cannot get current VBE mode"); + *mode = last_set_mode; return GRUB_ERR_NONE; } @@ -350,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); @@ -391,10 +398,6 @@ grub_video_vbe_setup (unsigned int width, unsigned int height, /* If not available, skip it. */ continue; - if ((vbe_mode_info.mode_attributes & 0x002) == 0) - /* Not enough information. */ - continue; - if ((vbe_mode_info.mode_attributes & 0x008) == 0) /* Monochrome is unusable. */ continue; @@ -497,7 +500,7 @@ grub_video_vbe_setup (unsigned int width, unsigned int height, } /* Couldn't found matching mode. */ - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching mode found."); + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching mode found"); } static grub_err_t diff --git a/video/readers/tga.c b/video/readers/tga.c index d0ca2770f..277458fa8 100644 --- a/video/readers/tga.c +++ b/video/readers/tga.c @@ -370,7 +370,7 @@ grub_video_reader_tga (struct grub_video_bitmap **bitmap, default: grub_file_close (file); return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "Unsupported bitmap format (unknown encoding)."); + "unsupported bitmap format (unknown encoding)"); } /* Check that bitmap depth is supported. */ @@ -387,7 +387,7 @@ grub_video_reader_tga (struct grub_video_bitmap **bitmap, default: grub_file_close (file); return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "Unsupported bitmap format (bpp=%d).", + "unsupported bitmap format (bpp=%d)", header.image_bpp); } diff --git a/video/video.c b/video/video.c index c1d66bdd0..682bebcbf 100644 --- a/video/video.c +++ b/video/video.c @@ -81,7 +81,7 @@ grub_err_t grub_video_get_info (struct grub_video_mode_info *mode_info) { if (! grub_video_adapter_active) - return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated"); /* If mode_info is NULL just report that video adapter is active. */ if (! mode_info) @@ -101,7 +101,7 @@ grub_video_get_info_and_fini (struct grub_video_mode_info *mode_info, grub_err_t err; if (! grub_video_adapter_active) - return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated"); err = grub_video_adapter_active->get_info_and_fini (mode_info, framebuffer); if (err) @@ -209,7 +209,7 @@ grub_video_set_palette (unsigned int start, unsigned int count, struct grub_video_palette_data *palette_data) { if (! grub_video_adapter_active) - return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated"); return grub_video_adapter_active->set_palette (start, count, palette_data); } @@ -220,7 +220,7 @@ grub_video_get_palette (unsigned int start, unsigned int count, struct grub_video_palette_data *palette_data) { if (! grub_video_adapter_active) - return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated"); return grub_video_adapter_active->get_palette (start, count, palette_data); } @@ -231,7 +231,7 @@ grub_video_set_viewport (unsigned int x, unsigned int y, unsigned int width, unsigned int height) { if (! grub_video_adapter_active) - return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated"); return grub_video_adapter_active->set_viewport (x, y, width, height); } @@ -242,7 +242,7 @@ grub_video_get_viewport (unsigned int *x, unsigned int *y, unsigned int *width, unsigned int *height) { if (! grub_video_adapter_active) - return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated"); return grub_video_adapter_active->get_viewport (x, y, width, height); } @@ -285,7 +285,7 @@ grub_video_unmap_color (grub_video_color_t color, grub_uint8_t *red, grub_uint8_t *alpha) { if (! grub_video_adapter_active) - return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated"); return grub_video_adapter_active->unmap_color (color, red, @@ -300,7 +300,7 @@ grub_video_fill_rect (grub_video_color_t color, int x, int y, unsigned int width, unsigned int height) { if (! grub_video_adapter_active) - return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated"); return grub_video_adapter_active->fill_rect (color, x, y, width, height); } @@ -313,7 +313,7 @@ grub_video_blit_bitmap (struct grub_video_bitmap *bitmap, unsigned int width, unsigned int height) { if (! grub_video_adapter_active) - return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated"); return grub_video_adapter_active->blit_bitmap (bitmap, oper, x, y, offset_x, offset_y, @@ -328,7 +328,7 @@ grub_video_blit_render_target (struct grub_video_render_target *target, unsigned int width, unsigned int height) { if (! grub_video_adapter_active) - return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated"); return grub_video_adapter_active->blit_render_target (target, oper, x, y, offset_x, offset_y, @@ -340,7 +340,7 @@ grub_err_t grub_video_scroll (grub_video_color_t color, int dx, int dy) { if (! grub_video_adapter_active) - return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated"); return grub_video_adapter_active->scroll (color, dx, dy); } @@ -350,7 +350,7 @@ grub_err_t grub_video_swap_buffers (void) { if (! grub_video_adapter_active) - return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated"); return grub_video_adapter_active->swap_buffers (); } @@ -362,7 +362,7 @@ grub_video_create_render_target (struct grub_video_render_target **result, unsigned int mode_type) { if (! grub_video_adapter_active) - return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated"); return grub_video_adapter_active->create_render_target (result, width, height, @@ -374,7 +374,7 @@ grub_err_t grub_video_delete_render_target (struct grub_video_render_target *target) { if (! grub_video_adapter_active) - return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated"); return grub_video_adapter_active->delete_render_target (target); } @@ -384,7 +384,7 @@ grub_err_t grub_video_set_active_render_target (struct grub_video_render_target *target) { if (! grub_video_adapter_active) - return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated"); return grub_video_adapter_active->set_active_render_target (target); } @@ -394,7 +394,7 @@ grub_err_t grub_video_get_active_render_target (struct grub_video_render_target **target) { if (! grub_video_adapter_active) - return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated"); + return grub_error (GRUB_ERR_BAD_DEVICE, "no video mode activated"); return grub_video_adapter_active->get_active_render_target (target); } @@ -460,7 +460,7 @@ grub_video_set_mode (const char *modestring, grub_free (modevar); return grub_error (GRUB_ERR_BAD_ARGUMENT, - "No suitable mode found."); + "no suitable mode found"); } /* Skip separator. */ @@ -545,7 +545,7 @@ grub_video_set_mode (const char *modestring, /* First setup error message. */ rc = grub_error (GRUB_ERR_BAD_ARGUMENT, - "Invalid mode: %s\n", + "invalid mode: %s", current_mode); /* Free memory before returning. */ @@ -564,7 +564,7 @@ grub_video_set_mode (const char *modestring, /* First setup error message. */ rc = grub_error (GRUB_ERR_BAD_ARGUMENT, - "Invalid mode: %s\n", + "invalid mode: %s", current_mode); /* Free memory before returning. */ @@ -585,7 +585,7 @@ grub_video_set_mode (const char *modestring, /* First setup error message. */ rc = grub_error (GRUB_ERR_BAD_ARGUMENT, - "Invalid mode: %s\n", + "invalid mode: %s", current_mode); /* Free memory before returning. */ @@ -607,7 +607,7 @@ grub_video_set_mode (const char *modestring, /* First setup error message. */ rc = grub_error (GRUB_ERR_BAD_ARGUMENT, - "Invalid mode: %s\n", + "invalid mode: %s", current_mode); /* Free memory before returning. */ @@ -625,7 +625,7 @@ grub_video_set_mode (const char *modestring, /* First setup error message. */ rc = grub_error (GRUB_ERR_BAD_ARGUMENT, - "Invalid mode: %s\n", + "invalid mode: %s", current_mode); /* Free memory before returning. */ @@ -709,7 +709,7 @@ grub_video_set_mode (const char *modestring, grub_free (modevar); return grub_error (GRUB_ERR_BAD_ARGUMENT, - "No suitable mode found."); + "no suitable mode found"); } /* Initialize Video API module. */