grub_err_t grub_multiboot_set_video_mode (void) { grub_err_t err; const char *modevar; #if GRUB_MACHINE_HAS_VGA_TEXT if (accepts_video) #endif { modevar = grub_env_get ("gfxpayload"); if (! modevar || *modevar == 0) err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0, 0); else { char *tmp; tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar); if (! tmp) return grub_errno; err = grub_video_set_mode (tmp, 0, 0); grub_free (tmp); } } #if GRUB_MACHINE_HAS_VGA_TEXT else err = grub_video_set_mode ("text", 0, 0); #endif return err; }
static grub_err_t grub_ntldr_boot (void) { struct grub_relocator16_state state = { .cs = GRUB_NTLDR_SEGMENT, .ip = 0, .ds = 0, .es = 0, .fs = 0, .gs = 0, .ss = 0, .sp = 0x7c00, .edx = edx }; grub_video_set_mode ("text", 0, 0); return grub_relocator16_boot (rel, state); } static grub_err_t grub_ntldr_unload (void) { grub_relocator_unload (rel); rel = NULL; grub_dl_unref (my_mod); return GRUB_ERR_NONE; }
static grub_err_t grub_freedos_boot (void) { struct grub_relocator16_state state = { .cs = GRUB_FREEDOS_SEGMENT, .ip = 0, .ds = GRUB_FREEDOS_STACK_SEGMENT, .es = 0, .fs = 0, .gs = 0, .ss = GRUB_FREEDOS_STACK_SEGMENT, .sp = GRUB_FREEDOS_STACK_POINTER, .ebp = GRUB_FREEDOS_STACK_BPB_POINTER, .ebx = ebx, .edx = ebx, .a20 = 1 }; grub_video_set_mode ("text", 0, 0); return grub_relocator16_boot (rel, state); } static grub_err_t grub_freedos_unload (void) { grub_relocator_unload (rel); rel = NULL; grub_dl_unref (my_mod); return GRUB_ERR_NONE; }
static grub_err_t grub_chainloader_boot (void) { grub_video_set_mode ("text", 0, 0); grub_chainloader_real_boot (boot_drive, boot_part_addr); /* Never reach here. */ return GRUB_ERR_NONE; }
static grub_err_t grub_chain_boot (void) { struct grub_relocator32_state state; grub_video_set_mode ("text", 0, 0); state.eip = entry; return grub_relocator32_boot (relocator, state, 0); }
static grub_err_t grub_pxechain_boot (void) { struct grub_relocator16_state state = { .cs = 0, .ip = 0x7c00, .ds = 0, .es = 0, .fs = 0, .gs = 0, .ss = 0, .sp = 0x7c00, .edx = edx }; struct grub_net_bootp_packet *bp; bp = grub_pxe_get_cached (GRUB_PXENV_PACKET_TYPE_DHCP_ACK); grub_video_set_mode ("text", 0, 0); if (bp && boot_file[0]) grub_memcpy (bp->boot_file, boot_file, sizeof (bp->boot_file)); if (bp && server_name[0]) grub_memcpy (bp->server_name, server_name, sizeof (bp->server_name)); return grub_relocator16_boot (rel, state); } static grub_err_t grub_pxechain_unload (void) { grub_relocator_unload (rel); rel = NULL; grub_dl_unref (my_mod); return GRUB_ERR_NONE; }
static grub_err_t grub_linux_boot (void) { grub_err_t err = 0; const char *modevar; char *tmp; struct grub_relocator32_state state; void *real_mode_mem; struct grub_linux_boot_ctx ctx = { .real_mode_target = 0 }; grub_size_t mmap_size; grub_size_t cl_offset; #ifdef GRUB_MACHINE_IEEE1275 { const char *bootpath; grub_ssize_t len; bootpath = grub_env_get ("root"); if (bootpath) grub_ieee1275_set_property (grub_ieee1275_chosen, "bootpath", bootpath, grub_strlen (bootpath) + 1, &len); linux_params.ofw_signature = GRUB_LINUX_OFW_SIGNATURE; linux_params.ofw_num_items = 1; linux_params.ofw_cif_handler = (grub_uint32_t) grub_ieee1275_entry_fn; linux_params.ofw_idt = 0; } #endif modevar = grub_env_get ("gfxpayload"); /* Now all graphical modes are acceptable. May change in future if we have modes without framebuffer. */ if (modevar && *modevar != 0) { tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar); if (! tmp) return grub_errno; #if ACCEPTS_PURE_TEXT err = grub_video_set_mode (tmp, 0, 0); #else err = grub_video_set_mode (tmp, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); #endif grub_free (tmp); } else /* We can't go back to text mode from coreboot fb. */ #ifdef GRUB_MACHINE_COREBOOT if (grub_video_get_driver_id () == GRUB_VIDEO_DRIVER_COREBOOT) err = GRUB_ERR_NONE; else #endif { #if ACCEPTS_PURE_TEXT err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0, 0); #else err = grub_video_set_mode (DEFAULT_VIDEO_MODE, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); #endif } if (err) { grub_print_error (); grub_puts_ (N_("Booting in blind mode")); grub_errno = GRUB_ERR_NONE; } if (grub_linux_setup_video (&linux_params)) { #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) linux_params.have_vga = GRUB_VIDEO_LINUX_TYPE_TEXT; linux_params.video_mode = 0x3; #else linux_params.have_vga = 0; linux_params.video_mode = 0; linux_params.video_width = 0; linux_params.video_height = 0; #endif } #ifndef GRUB_MACHINE_IEEE1275 if (linux_params.have_vga == GRUB_VIDEO_LINUX_TYPE_TEXT) #endif { grub_term_output_t term; int found = 0; FOR_ACTIVE_TERM_OUTPUTS(term) if (grub_strcmp (term->name, "vga_text") == 0 || grub_strcmp (term->name, "console") == 0 || grub_strcmp (term->name, "ofconsole") == 0) { struct grub_term_coordinate pos = grub_term_getxy (term); linux_params.video_cursor_x = pos.x; linux_params.video_cursor_y = pos.y; linux_params.video_width = grub_term_width (term); linux_params.video_height = grub_term_height (term); found = 1; break; } if (!found) { linux_params.video_cursor_x = 0; linux_params.video_cursor_y = 0; linux_params.video_width = 80; linux_params.video_height = 25; } } mmap_size = find_mmap_size (); /* Make sure that each size is aligned to a page boundary. */ cl_offset = ALIGN_UP (mmap_size + sizeof (linux_params), 4096); if (cl_offset < ((grub_size_t) linux_params.setup_sects << GRUB_DISK_SECTOR_BITS)) cl_offset = ALIGN_UP ((grub_size_t) (linux_params.setup_sects << GRUB_DISK_SECTOR_BITS), 4096); ctx.real_size = ALIGN_UP (cl_offset + maximal_cmdline_size, 4096); #ifdef GRUB_MACHINE_EFI efi_mmap_size = find_efi_mmap_size (); if (efi_mmap_size == 0) return grub_errno; #endif grub_dprintf ("linux", "real_size = %x, mmap_size = %x\n", (unsigned) ctx.real_size, (unsigned) mmap_size); #ifdef GRUB_MACHINE_EFI grub_efi_mmap_iterate (grub_linux_boot_mmap_find, &ctx, 1); if (! ctx.real_mode_target) grub_efi_mmap_iterate (grub_linux_boot_mmap_find, &ctx, 0); #else grub_mmap_iterate (grub_linux_boot_mmap_find, &ctx); #endif grub_dprintf ("linux", "real_mode_target = %lx, real_size = %x, efi_mmap_size = %x\n", (unsigned long) ctx.real_mode_target, (unsigned) ctx.real_size, (unsigned) efi_mmap_size); if (! ctx.real_mode_target) return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages"); { grub_relocator_chunk_t ch; err = grub_relocator_alloc_chunk_addr (relocator, &ch, ctx.real_mode_target, (ctx.real_size + efi_mmap_size)); if (err) return err; real_mode_mem = get_virtual_current_address (ch); } efi_mmap_buf = (grub_uint8_t *) real_mode_mem + ctx.real_size; grub_dprintf ("linux", "real_mode_mem = %p\n", real_mode_mem); ctx.params = real_mode_mem; *ctx.params = linux_params; ctx.params->cmd_line_ptr = ctx.real_mode_target + cl_offset; grub_memcpy ((char *) ctx.params + cl_offset, linux_cmdline, maximal_cmdline_size); grub_dprintf ("linux", "code32_start = %x\n", (unsigned) ctx.params->code32_start); ctx.e820_num = 0; if (grub_mmap_iterate (grub_linux_boot_mmap_fill, &ctx)) return grub_errno; ctx.params->mmap_size = ctx.e820_num; #ifdef GRUB_MACHINE_EFI { grub_efi_uintn_t efi_desc_size; grub_size_t efi_mmap_target; grub_efi_uint32_t efi_desc_version; err = grub_efi_finish_boot_services (&efi_mmap_size, efi_mmap_buf, NULL, &efi_desc_size, &efi_desc_version); if (err) return err; /* Note that no boot services are available from here. */ efi_mmap_target = ctx.real_mode_target + ((grub_uint8_t *) efi_mmap_buf - (grub_uint8_t *) real_mode_mem); /* Pass EFI parameters. */ if (grub_le_to_cpu16 (ctx.params->version) >= 0x0208) { ctx.params->v0208.efi_mem_desc_size = efi_desc_size; ctx.params->v0208.efi_mem_desc_version = efi_desc_version; ctx.params->v0208.efi_mmap = efi_mmap_target; ctx.params->v0208.efi_mmap_size = efi_mmap_size; #ifdef __x86_64__ ctx.params->v0208.efi_mmap_hi = (efi_mmap_target >> 32); #endif } else if (grub_le_to_cpu16 (ctx.params->version) >= 0x0206)
static grub_err_t grub_cmd_videotest (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) { grub_err_t err; grub_video_color_t color; unsigned int x; unsigned int y; unsigned int width; unsigned int height; int i; struct grub_video_render_target *text_layer; grub_video_color_t palette[16]; const char *mode = NULL; #ifdef GRUB_MACHINE_PCBIOS if (grub_strcmp (cmd->name, "vbetest") == 0) grub_dl_load ("vbe"); #endif mode = grub_env_get ("gfxmode"); if (argc) mode = args[0]; if (!mode) mode = "auto"; err = grub_video_set_mode (mode, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); if (err) return err; grub_video_get_viewport (&x, &y, &width, &height); { const char *str; int texty; grub_font_t sansbig; grub_font_t sans; grub_font_t sanssmall; grub_font_t fixed; struct grub_font_glyph *glyph; grub_video_create_render_target (&text_layer, width, height, GRUB_VIDEO_MODE_TYPE_RGB | GRUB_VIDEO_MODE_TYPE_ALPHA); grub_video_set_active_render_target (text_layer); color = grub_video_map_rgb (0, 255, 255); sansbig = grub_font_get ("Unknown Regular 16"); sans = grub_font_get ("Unknown Regular 16"); sanssmall = grub_font_get ("Unknown Regular 16"); fixed = grub_font_get ("Fixed 20"); if (! sansbig || ! sans || ! sanssmall || ! fixed) return grub_error (GRUB_ERR_BAD_FONT, "no font loaded"); glyph = grub_font_get_glyph (fixed, '*'); grub_font_draw_glyph (glyph, color, 200 ,0); color = grub_video_map_rgb (255, 255, 255); texty = 32; grub_font_draw_string ("The quick brown fox jumped over the lazy dog.", sans, color, 16, texty); texty += grub_font_get_descent (sans) + grub_font_get_leading (sans); texty += grub_font_get_ascent (fixed); grub_font_draw_string ("The quick brown fox jumped over the lazy dog.", fixed, color, 16, texty); texty += grub_font_get_descent (fixed) + grub_font_get_leading (fixed); /* To convert Unicode characters into UTF-8 for this test, the following command is useful: echo -ne '\x00\x00\x26\x3A' | iconv -f UTF-32BE -t UTF-8 | od -t x1 This converts the Unicode character U+263A to UTF-8. */ /* Characters used: Code point Description UTF-8 encoding ----------- ------------------------------ -------------- U+263A unfilled smiley face E2 98 BA U+00A1 inverted exclamation point C2 A1 U+00A3 British pound currency symbol C2 A3 U+03C4 Greek tau CF 84 U+00E4 lowercase letter a with umlaut C3 A4 U+2124 set 'Z' symbol (integers) E2 84 A4 U+2287 subset symbol E2 8A 87 U+211D set 'R' symbol (real numbers) E2 84 9D */ str = "Unicode test: happy\xE2\x98\xBA \xC2\xA3 5.00" " \xC2\xA1\xCF\x84\xC3\xA4u! " " \xE2\x84\xA4\xE2\x8A\x87\xE2\x84\x9D"; color = grub_video_map_rgb (128, 128, 255); /* All characters in the string exist in the 'Fixed 20' (10x20) font. */ texty += grub_font_get_ascent(fixed); grub_font_draw_string (str, fixed, color, 16, texty); texty += grub_font_get_descent (fixed) + grub_font_get_leading (fixed); texty += grub_font_get_ascent(sansbig); grub_font_draw_string (str, sansbig, color, 16, texty); texty += grub_font_get_descent (sansbig) + grub_font_get_leading (sansbig); texty += grub_font_get_ascent(sans); grub_font_draw_string (str, sans, color, 16, texty); texty += grub_font_get_descent (sans) + grub_font_get_leading (sans); texty += grub_font_get_ascent(sanssmall); grub_font_draw_string (str, sanssmall, color, 16, texty); texty += (grub_font_get_descent (sanssmall) + grub_font_get_leading (sanssmall)); glyph = grub_font_get_glyph (fixed, '*'); for (i = 0; i < 16; i++) { color = grub_video_map_color (i); palette[i] = color; grub_font_draw_glyph (glyph, color, 16 + i * 16, 220); } } grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); for (i = 0; i < 2; i++) { color = grub_video_map_rgb (0, 0, 0); grub_video_fill_rect (color, 0, 0, width, height); color = grub_video_map_rgb (255, 0, 0); grub_video_fill_rect (color, 0, 0, 100, 100); color = grub_video_map_rgb (0, 255, 255); grub_video_fill_rect (color, 100, 100, 100, 100); grub_video_set_viewport (x + 150, y + 150, width - 150 * 2, height - 150 * 2); color = grub_video_map_rgb (77, 33, 77); grub_video_fill_rect (color, 0, 0, width, height); grub_video_swap_buffers (); } for (i = 0; i < 5; i++) { color = grub_video_map_rgb (i, 33, 77); grub_video_fill_rect (color, 0, 0, width, height); grub_video_blit_render_target (text_layer, GRUB_VIDEO_BLIT_BLEND, 0, 0, 0, 0, width, height); grub_video_swap_buffers (); } grub_getkey (); grub_video_delete_render_target (text_layer); grub_video_restore (); for (i = 0; i < 16; i++) grub_printf("color %d: %08x\n", i, palette[i]); grub_errno = GRUB_ERR_NONE; return grub_errno; }
static grub_err_t grub_linux_boot (void) { grub_err_t err = 0; const char *modevar; char *tmp; struct grub_relocator32_state state; void *real_mode_mem; struct grub_linux_boot_ctx ctx = { .real_mode_target = 0 }; grub_size_t mmap_size; grub_size_t cl_offset; #ifdef GRUB_MACHINE_IEEE1275 { const char *bootpath; grub_ssize_t len; bootpath = grub_env_get ("root"); if (bootpath) grub_ieee1275_set_property (grub_ieee1275_chosen, "bootpath", bootpath, grub_strlen (bootpath) + 1, &len); linux_params.ofw_signature = GRUB_LINUX_OFW_SIGNATURE; linux_params.ofw_num_items = 1; linux_params.ofw_cif_handler = (grub_uint32_t) grub_ieee1275_entry_fn; linux_params.ofw_idt = 0; } #endif modevar = grub_env_get ("gfxpayload"); /* Now all graphical modes are acceptable. May change in future if we have modes without framebuffer. */ if (modevar && *modevar != 0) { tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar); if (! tmp) return grub_errno; #if ACCEPTS_PURE_TEXT err = grub_video_set_mode (tmp, 0, 0); #else err = grub_video_set_mode (tmp, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); #endif grub_free (tmp); } else /* We can't go back to text mode from coreboot fb. */ #ifdef GRUB_MACHINE_COREBOOT if (grub_video_get_driver_id () == GRUB_VIDEO_DRIVER_COREBOOT) err = GRUB_ERR_NONE; else #endif { #if ACCEPTS_PURE_TEXT err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0, 0); #else err = grub_video_set_mode (DEFAULT_VIDEO_MODE, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); #endif } if (err) { grub_print_error (); grub_puts_ (N_("Booting in blind mode")); grub_errno = GRUB_ERR_NONE; } if (grub_linux_setup_video (&linux_params)) { #if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) linux_params.have_vga = GRUB_VIDEO_LINUX_TYPE_TEXT; linux_params.video_mode = 0x3; #else linux_params.have_vga = 0; linux_params.video_mode = 0; linux_params.video_width = 0; linux_params.video_height = 0; #endif } #ifndef GRUB_MACHINE_IEEE1275 if (linux_params.have_vga == GRUB_VIDEO_LINUX_TYPE_TEXT) #endif { grub_term_output_t term; int found = 0; FOR_ACTIVE_TERM_OUTPUTS(term) if (grub_strcmp (term->name, "vga_text") == 0 || grub_strcmp (term->name, "console") == 0 || grub_strcmp (term->name, "ofconsole") == 0) { grub_uint16_t pos = grub_term_getxy (term); linux_params.video_cursor_x = pos >> 8; linux_params.video_cursor_y = pos & 0xff; linux_params.video_width = grub_term_width (term); linux_params.video_height = grub_term_height (term); found = 1; break; } if (!found) { linux_params.video_cursor_x = 0; linux_params.video_cursor_y = 0; linux_params.video_width = 80; linux_params.video_height = 25; } }