From: Vladimir 'phcoder' Serbinenko Date: Wed, 20 Jan 2010 10:48:36 +0000 (+0100) Subject: merge bootcheck and mainline into newreloc X-Git-Tag: 1.99~629^2~117 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3c83bc50db772fb2241cbff2314028b71de2337b;p=thirdparty%2Fgrub.git merge bootcheck and mainline into newreloc --- 3c83bc50db772fb2241cbff2314028b71de2337b diff --cc conf/i386-efi.rmk index 959cc2355,cbadc7e1a..3170784be --- a/conf/i386-efi.rmk +++ b/conf/i386-efi.rmk @@@ -30,8 -30,9 +30,9 @@@ sbin_SCRIPTS = grub-instal grub_install_SOURCES = util/i386/efi/grub-install.in # Modules. - pkglib_MODULES = kernel.img chain.mod appleldr.mod \ + pkglib_PROGRAMS = kernel.img + pkglib_MODULES = chain.mod appleldr.mod \ - linux.mod halt.mod reboot.mod pci.mod lspci.mod \ + halt.mod reboot.mod pci.mod lspci.mod \ datetime.mod date.mod datehook.mod loadbios.mod \ fixvideo.mod mmap.mod acpi.mod diff --cc conf/i386.rmk index 690194261,c25e60d88..aa2ec21df --- a/conf/i386.rmk +++ b/conf/i386.rmk @@@ -63,12 -42,6 +63,12 @@@ multiboot2_mod_CFLAGS = $(COMMON_CFLAGS multiboot2_mod_LDFLAGS = $(COMMON_LDFLAGS) multiboot2_mod_ASFLAGS = $(COMMON_ASFLAGS) +# For serial.mod. +pkglib_MODULES += serial.mod - serial_mod_SOURCES = term/i386/pc/serial.c ++serial_mod_SOURCES = term/serial.c +serial_mod_CFLAGS = $(COMMON_CFLAGS) +serial_mod_LDFLAGS = $(COMMON_LDFLAGS) + linux.init.x86_64: $(srcdir)/tests/boot/linux.init-x86_64.S $(TARGET_CC) -o $@ $< -m64 -nostdlib -nostdinc -DSUCCESSFUL_BOOT_STRING=\"$(SUCCESSFUL_BOOT_STRING)\" diff --cc conf/x86_64-efi.rmk index b73773dbb,e5b3aec25..a4d1970aa --- a/conf/x86_64-efi.rmk +++ b/conf/x86_64-efi.rmk @@@ -29,8 -29,9 +29,9 @@@ sbin_SCRIPTS = grub-instal grub_install_SOURCES = util/i386/efi/grub-install.in # Modules. - pkglib_MODULES = kernel.img chain.mod appleldr.mod \ + pkglib_PROGRAMS = kernel.img + pkglib_MODULES = chain.mod appleldr.mod \ - halt.mod reboot.mod linux.mod pci.mod lspci.mod \ + halt.mod reboot.mod pci.mod lspci.mod \ datetime.mod date.mod datehook.mod loadbios.mod \ fixvideo.mod mmap.mod acpi.mod diff --cc include/grub/elfload.h index 1e640c198,77ee41675..83fb9128a --- a/include/grub/elfload.h +++ b/include/grub/elfload.h @@@ -51,16 -51,8 +51,16 @@@ grub_err_t grub_elf32_load (grub_elf_t grub_size_t *); int grub_elf_is_elf64 (grub_elf_t); - grub_size_t grub_elf64_size (grub_elf_t); + grub_size_t grub_elf64_size (grub_elf_t, Elf64_Addr *); grub_err_t grub_elf64_load (grub_elf_t, grub_elf64_load_hook_t, grub_addr_t *, grub_size_t *); +grub_err_t +grub_elf32_phdr_iterate (grub_elf_t elf, + int NESTED_FUNC_ATTR (*hook) (grub_elf_t, Elf32_Phdr *, void *), + void *hook_arg); +grub_err_t +grub_elf64_phdr_iterate (grub_elf_t elf, + int NESTED_FUNC_ATTR (*hook) (grub_elf_t, Elf64_Phdr *, void *), + void *hook_arg); #endif /* ! GRUB_ELFLOAD_HEADER */ diff --cc include/grub/i386/efi/serial.h index 000000000,000000000..2d8563414 new file mode 100644 --- /dev/null +++ b/include/grub/i386/efi/serial.h @@@ -1,0 -1,0 +1,1 @@@ ++#include diff --cc include/grub/serial.h index 4038f50fb,1c35b4093..30daeb6ae --- a/include/grub/serial.h +++ b/include/grub/serial.h @@@ -64,7 -64,4 +64,9 @@@ /* Turn on DTR, RTS, and OUT2. */ #define UART_ENABLE_MODEM 0x0B - unsigned short ++#include ++ ++grub_port_t +grub_serial_hw_get_port (const unsigned int unit); + #endif /* ! GRUB_SERIAL_MACHINE_HEADER */ diff --cc include/grub/x86_64/efi/serial.h index 000000000,000000000..2d8563414 new file mode 100644 --- /dev/null +++ b/include/grub/x86_64/efi/serial.h @@@ -1,0 -1,0 +1,1 @@@ ++#include diff --cc loader/i386/bsd.c index 7a8ddb89a,2598371b7..9e222244e --- a/loader/i386/bsd.c +++ b/loader/i386/bsd.c @@@ -33,8 -35,6 +33,8 @@@ #include #include #include - #include ++#include + #include #ifdef GRUB_MACHINE_PCBIOS #include @@@ -833,208 -631,100 +833,206 @@@ grub_openbsd_boot (void } static grub_err_t -grub_netbsd_boot (void) +grub_netbsd_setup_video (void) { - struct grub_netbsd_bootinfo *bootinfo; - int count = 0; - struct grub_netbsd_btinfo_mmap_header *mmap; - struct grub_netbsd_btinfo_mmap_entry *pm; - void *curarg; - - auto int NESTED_FUNC_ATTR count_hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); - int NESTED_FUNC_ATTR count_hook (grub_uint64_t addr __attribute__ ((unused)), - grub_uint64_t size __attribute__ ((unused)), - grub_uint32_t type __attribute__ ((unused))) - { - count++; - return 0; - } - - auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t, grub_uint32_t); - int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type) - { - pm->addr = addr; - pm->len = size; + struct grub_video_mode_info mode_info; + void *framebuffer; + const char *modevar; + struct grub_netbsd_btinfo_framebuf params; + grub_err_t err; + grub_video_driver_id_t driv_id; - switch (type) - { - case GRUB_MACHINE_MEMORY_AVAILABLE: - pm->type = NETBSD_MMAP_AVAILABLE; - break; + modevar = grub_env_get ("gfxpayload"); - case GRUB_MACHINE_MEMORY_ACPI: - pm->type = NETBSD_MMAP_ACPI; - break; + /* Now all graphical modes are acceptable. + May change in future if we have modes without framebuffer. */ + if (modevar && *modevar != 0) + { + char *tmp; - tmp = grub_malloc (grub_strlen (modevar) - + sizeof (";" NETBSD_DEFAULT_VIDEO_MODE)); ++ tmp = grub_xasprintf ("%s;" NETBSD_DEFAULT_VIDEO_MODE, modevar); + if (! tmp) + return grub_errno; - grub_sprintf (tmp, "%s;" NETBSD_DEFAULT_VIDEO_MODE, modevar); + err = grub_video_set_mode (tmp, 0, 0); + grub_free (tmp); + } + else + err = grub_video_set_mode (NETBSD_DEFAULT_VIDEO_MODE, 0, 0); - case GRUB_MACHINE_MEMORY_NVS: - pm->type = NETBSD_MMAP_NVS; - break; + if (err) + return err; - default: - pm->type = NETBSD_MMAP_RESERVED; - break; - } - pm++; + driv_id = grub_video_get_driver_id (); + if (driv_id == GRUB_VIDEO_DRIVER_NONE) + return GRUB_ERR_NONE; - return 0; - } + err = grub_video_get_info_and_fini (&mode_info, &framebuffer); - grub_mmap_iterate (count_hook); + if (err) + return err; - if (kern_end + sizeof (struct grub_netbsd_btinfo_rootdevice) - + sizeof (struct grub_netbsd_bootinfo) - + 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, "out of memory"); + params.width = mode_info.width; + params.height = mode_info.height; + params.bpp = mode_info.bpp; + params.pitch = mode_info.pitch; + params.flags = 0; - curarg = mmap = (struct grub_netbsd_btinfo_mmap_header *) kern_end; - pm = (struct grub_netbsd_btinfo_mmap_entry *) (mmap + 1); + params.fbaddr = (grub_addr_t) framebuffer; - grub_mmap_iterate (fill_hook); - mmap->common.type = NETBSD_BTINFO_MEMMAP; - mmap->common.len = (char *) pm - (char *) mmap; - mmap->count = count; - curarg = pm; + params.red_mask_size = mode_info.red_mask_size; + params.red_field_pos = mode_info.red_field_pos; + params.green_mask_size = mode_info.green_mask_size; + params.green_field_pos = mode_info.green_field_pos; + params.blue_mask_size = mode_info.blue_mask_size; + params.blue_field_pos = mode_info.blue_field_pos; - if (netbsd_root) +#ifdef GRUB_MACHINE_PCBIOS + /* VESA packed modes may come with zeroed mask sizes, which need + to be set here according to DAC Palette width. If we don't, + this results in Linux displaying a black screen. */ + if (mode_info.bpp <= 8 && driv_id == GRUB_VIDEO_DRIVER_VBE) { - struct grub_netbsd_btinfo_rootdevice *rootdev; + struct grub_vbe_info_block controller_info; + int status; + int width = 8; + + status = grub_vbe_bios_get_controller_info (&controller_info); - rootdev = (struct grub_netbsd_btinfo_rootdevice *) curarg; + if (status == GRUB_VBE_STATUS_OK && + (controller_info.capabilities & GRUB_VBE_CAPABILITY_DACWIDTH)) + status = grub_vbe_bios_set_dac_palette_width (&width); - rootdev->common.len = sizeof (struct grub_netbsd_btinfo_rootdevice); - rootdev->common.type = NETBSD_BTINFO_ROOTDEVICE; - grub_strncpy (rootdev->devname, netbsd_root, sizeof (rootdev->devname)); + if (status != GRUB_VBE_STATUS_OK) + /* 6 is default after mode reset. */ + width = 6; - bootinfo = (struct grub_netbsd_bootinfo *) (rootdev + 1); - bootinfo->bi_count = 2; - bootinfo->bi_data[0] = mmap; - bootinfo->bi_data[1] = rootdev; + params.red_mask_size = params.green_mask_size + = params.blue_mask_size = width; } - else +#endif + + err = grub_bsd_add_meta (NETBSD_BTINFO_FRAMEBUF, ¶ms, sizeof (params)); + return err; +} + +static grub_err_t +grub_netbsd_add_modules (void) +{ + struct netbsd_module *mod; + unsigned modcnt = 0; + struct grub_netbsd_btinfo_modules *mods; + unsigned i; + grub_err_t err; + + for (mod = netbsd_mods; mod; mod = mod->next) + modcnt++; + + mods = grub_malloc (sizeof (*mods) + sizeof (mods->mods[0]) * modcnt); + if (!mods) + return grub_errno; + + mods->num = modcnt; + mods->last_addr = kern_end; + for (mod = netbsd_mods, i = 0; mod; i++, mod = mod->next) + mods->mods[i] = mod->mod; + + err = grub_bsd_add_meta (NETBSD_BTINFO_MODULES, mods, + sizeof (*mods) + sizeof (mods->mods[0]) * modcnt); + grub_free (mods); + return err; +} + +static grub_err_t +grub_netbsd_boot (void) +{ + struct grub_netbsd_bootinfo *bootinfo; + void *curarg, *arg0; + grub_addr_t arg_target, stack_target; + grub_uint32_t *stack; + grub_err_t err; + struct grub_relocator32_state state; + grub_size_t tag_buf_len = 0; + int tag_count = 0; + + err = grub_bsd_add_mmap (); + if (err) + return err; + + err = grub_netbsd_setup_video (); + if (err) { - bootinfo = (struct grub_netbsd_bootinfo *) curarg; - bootinfo->bi_count = 1; - bootinfo->bi_data[0] = mmap; + grub_print_error (); + grub_printf ("Booting however\n"); + grub_errno = GRUB_ERR_NONE; } - grub_video_set_mode ("text", 0, 0); + err = grub_netbsd_add_modules (); + if (err) + return err; - grub_unix_real_boot (entry, bootflags, 0, bootinfo, - 0, (grub_uint32_t) (grub_mmap_get_upper () >> 10), - (grub_uint32_t) (grub_mmap_get_lower () >> 10)); + { + struct bsd_tag *tag; + tag_buf_len = 0; + for (tag = tags; tag; tag = tag->next) + { + tag_buf_len = ALIGN_VAR (tag_buf_len + + sizeof (struct grub_netbsd_btinfo_common) + + tag->len); + tag_count++; + } + } - /* Not reached. */ - return GRUB_ERR_NONE; + arg_target = kern_end; + err = grub_relocator_alloc_chunk_addr (relocator, &curarg, + arg_target, tag_buf_len + + sizeof (struct grub_netbsd_bootinfo) + + tag_count * sizeof (grub_uint32_t)); + if (err) + return err; + + arg0 = curarg; + bootinfo = (void *) ((grub_uint8_t *) arg0 + tag_buf_len); + + { + struct bsd_tag *tag; + unsigned i; + + bootinfo->bi_count = tag_count; + for (tag = tags, i = 0; tag; i++, tag = tag->next) + { + struct grub_netbsd_btinfo_common *head = curarg; + bootinfo->bi_data[i] = ((grub_uint8_t *) curarg - (grub_uint8_t *) arg0) + + arg_target; + head->type = tag->type; + head->len = tag->len + sizeof (*head); + curarg = head + 1; + grub_memcpy (curarg, tag->data, tag->len); + curarg = (grub_uint8_t *) curarg + tag->len; + } + } + + err = grub_relocator_alloc_chunk_align (relocator, (void **) &stack, + &stack_target, 0x10000, 0x90000, + 7 * sizeof (grub_uint32_t), 4, + GRUB_RELOCATOR_PREFERENCE_NONE); + if (err) + return err; + +#ifdef GRUB_MACHINE_EFI + if (! grub_efi_finish_boot_services ()) + grub_fatal ("cannot exit boot services"); +#endif + + state.eip = entry; + state.esp = stack_target; + stack[0] = entry; + stack[1] = bootflags; + stack[2] = 0; + stack[3] = ((grub_uint8_t *) bootinfo - (grub_uint8_t *) arg0) + arg_target; + stack[4] = 0; + stack[5] = grub_mmap_get_upper () >> 10; + stack[6] = grub_mmap_get_lower () >> 10; + + return grub_relocator32_boot (relocator, state); } static grub_err_t diff --cc loader/i386/linux.c index af3b37ac4,5d9edbe7d..bfee316e3 --- a/loader/i386/linux.c +++ b/loader/i386/linux.c @@@ -612,11 -519,9 +612,9 @@@ grub_linux_boot (void May change in future if we have modes without framebuffer. */ if (modevar && *modevar != 0) { - tmp = grub_malloc (grub_strlen (modevar) - + sizeof (";" DEFAULT_VIDEO_MODE)); - tmp = grub_xasprintf ("%s;text", modevar); ++ tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar); if (! tmp) return grub_errno; - grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar); err = grub_video_set_mode (tmp, 0, 0); grub_free (tmp); } diff --cc loader/i386/xnu.c index a39f2bc7d,8000579d0..8040e65e3 --- a/loader/i386/xnu.c +++ b/loader/i386/xnu.c @@@ -836,85 -834,8 +838,83 @@@ grub_xnu_boot_resume (void state.eip = grub_xnu_entry_point; state.eax = grub_xnu_arg1; - return grub_relocator32_boot (grub_xnu_heap_start, grub_xnu_heap_will_be_at, - state); + return grub_relocator32_boot (grub_xnu_relocator, state); +} + +/* Setup video for xnu. */ +static grub_err_t +grub_xnu_set_video (struct grub_xnu_boot_params *params) +{ + struct grub_video_mode_info mode_info; + int ret; + char *tmp, *modevar; + void *framebuffer; + grub_err_t err; + + modevar = grub_env_get ("gfxpayload"); + /* Consider only graphical 32-bit deep modes. */ + if (! modevar || *modevar == 0) + err = grub_video_set_mode (DEFAULT_VIDEO_MODE, + GRUB_VIDEO_MODE_TYPE_PURE_TEXT + | GRUB_VIDEO_MODE_TYPE_DEPTH_MASK, + 32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS); + else + { - tmp = grub_malloc (grub_strlen (modevar) - + sizeof (DEFAULT_VIDEO_MODE) + 1); ++ tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar); + if (! tmp) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "couldn't allocate temporary storag"); - grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar); + err = grub_video_set_mode (tmp, + GRUB_VIDEO_MODE_TYPE_PURE_TEXT + | GRUB_VIDEO_MODE_TYPE_DEPTH_MASK, + 32 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS); + grub_free (tmp); + } + + if (err) + return err; + + if (grub_xnu_bitmap) + { + int x, y; + + x = mode_info.width - grub_xnu_bitmap->mode_info.width; + x /= 2; + y = mode_info.height - grub_xnu_bitmap->mode_info.height; + y /= 2; + err = grub_video_blit_bitmap (grub_xnu_bitmap, + GRUB_VIDEO_BLIT_REPLACE, + x > 0 ? x : 0, + y > 0 ? y : 0, + x < 0 ? -x : 0, + y < 0 ? -y : 0, + min (grub_xnu_bitmap->mode_info.width, + mode_info.width), + min (grub_xnu_bitmap->mode_info.height, + mode_info.height)); + if (err) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + grub_xnu_bitmap = 0; + } + err = GRUB_ERR_NONE; + } + + ret = grub_video_get_info_and_fini (&mode_info, &framebuffer); + if (ret) + return grub_error (GRUB_ERR_IO, "couldn't retrieve video parameters"); + + params->lfb_width = mode_info.width; + params->lfb_height = mode_info.height; + params->lfb_depth = mode_info.bpp; + params->lfb_line_len = mode_info.pitch; + + params->lfb_base = PTR_TO_UINT32 (framebuffer); + params->lfb_mode = grub_xnu_bitmap + ? GRUB_XNU_VIDEO_SPLASH : GRUB_XNU_VIDEO_TEXT_IN_VIDEO; + + return GRUB_ERR_NONE; } /* Boot xnu. */ diff --cc term/serial.c index 135bb6cc5,62cd11fee..9a195f0e7 --- a/term/serial.c +++ b/term/serial.c @@@ -73,8 -75,8 +75,8 @@@ static const grub_port_t serial_hw_io_a #endif /* Return the port number for the UNITth serial device. */ - unsigned short -static inline grub_port_t -serial_hw_get_port (const unsigned int unit) ++grub_port_t +grub_serial_hw_get_port (const unsigned int unit) { if (unit < GRUB_SERIAL_PORT_NUM) return serial_hw_io_addr[unit]; @@@ -603,11 -608,11 +608,11 @@@ GRUB_MOD_INIT(serial { cmd = grub_register_extcmd ("serial", grub_cmd_serial, GRUB_COMMAND_FLAG_BOTH, - N_("[OPTIONS...]"), - N_("Configure serial port."), options); + "serial [OPTIONS...]", + "Configure serial port.", options); /* Set default settings. */ - serial_settings.port = serial_hw_get_port (0); + serial_settings.port = grub_serial_hw_get_port (0); serial_settings.divisor = serial_get_divisor (9600); serial_settings.word_len = UART_8BITS_WORD; serial_settings.parity = UART_NO_PARITY;