static void fill_vbe_tag (struct multiboot_tag_vbe *tag) { grub_vbe_status_t status; void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; tag->type = MULTIBOOT_TAG_TYPE_VBE; tag->size = 0; status = grub_vbe_bios_get_controller_info (scratch); if (status != GRUB_VBE_STATUS_OK) return; grub_memcpy (&tag->vbe_control_info, scratch, sizeof (struct grub_vbe_info_block)); status = grub_vbe_bios_get_mode (scratch); tag->vbe_mode = *(grub_uint32_t *) scratch; if (status != GRUB_VBE_STATUS_OK) return; /* get_mode_info isn't available for mode 3. */ if (tag->vbe_mode == 3) { struct grub_vbe_mode_info_block *mode_info = (void *) &tag->vbe_mode_info; grub_memset (mode_info, 0, sizeof (struct grub_vbe_mode_info_block)); mode_info->memory_model = GRUB_VBE_MEMORY_MODEL_TEXT; mode_info->x_resolution = 80; mode_info->y_resolution = 25; } else { status = grub_vbe_bios_get_mode_info (tag->vbe_mode, scratch); if (status != GRUB_VBE_STATUS_OK) return; grub_memcpy (&tag->vbe_mode_info, scratch, sizeof (struct grub_vbe_mode_info_block)); } grub_vbe_bios_get_pm_interface (&tag->vbe_interface_seg, &tag->vbe_interface_off, &tag->vbe_interface_len); tag->size = sizeof (*tag); }
static grub_err_t fill_vbe_info (struct multiboot_info *mbi, grub_uint8_t *ptrorig, grub_uint32_t ptrdest, int fill_generic) { grub_uint32_t vbe_mode; struct grub_vbe_mode_info_block *mode_info; #if GRUB_MACHINE_HAS_VBE grub_vbe_status_t status; void *scratch = (void *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR; status = grub_vbe_bios_get_controller_info (scratch); if (status != GRUB_VBE_STATUS_OK) return grub_error (GRUB_ERR_IO, "Can't get controller info."); mbi->vbe_control_info = ptrdest; grub_memcpy (ptrorig, scratch, sizeof (struct grub_vbe_info_block)); ptrorig += sizeof (struct grub_vbe_info_block); ptrdest += sizeof (struct grub_vbe_info_block); #else mbi->vbe_control_info = 0; #endif #if GRUB_MACHINE_HAS_VBE status = grub_vbe_bios_get_mode (scratch); vbe_mode = *(grub_uint32_t *) scratch; if (status != GRUB_VBE_STATUS_OK) return grub_error (GRUB_ERR_IO, "can't get VBE mode"); #else vbe_mode = 3; #endif mbi->vbe_mode = vbe_mode; mode_info = (struct grub_vbe_mode_info_block *) ptrorig; mbi->vbe_mode_info = ptrdest; /* get_mode_info isn't available for mode 3. */ if (vbe_mode == 3) { grub_memset (mode_info, 0, sizeof (struct grub_vbe_mode_info_block)); mode_info->memory_model = GRUB_VBE_MEMORY_MODEL_TEXT; mode_info->x_resolution = 80; mode_info->y_resolution = 25; } else { #if GRUB_MACHINE_HAS_VBE status = grub_vbe_bios_get_mode_info (vbe_mode, scratch); if (status != GRUB_VBE_STATUS_OK) return grub_error (GRUB_ERR_IO, "can't get mode info"); grub_memcpy (mode_info, scratch, sizeof (struct grub_vbe_mode_info_block)); #endif } ptrorig += sizeof (struct grub_vbe_mode_info_block); ptrdest += sizeof (struct grub_vbe_mode_info_block); #if GRUB_MACHINE_HAS_VBE grub_vbe_bios_get_pm_interface (&mbi->vbe_interface_seg, &mbi->vbe_interface_off, &mbi->vbe_interface_len); #endif mbi->flags |= MULTIBOOT_INFO_VBE_INFO; if (fill_generic && mode_info->memory_model == GRUB_VBE_MEMORY_MODEL_TEXT) { mbi->framebuffer_addr = 0xb8000; mbi->framebuffer_pitch = 2 * mode_info->x_resolution; mbi->framebuffer_width = mode_info->x_resolution; mbi->framebuffer_height = mode_info->y_resolution; mbi->framebuffer_bpp = 16; mbi->framebuffer_type = MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT; mbi->flags |= MULTIBOOT_INFO_FRAMEBUFFER_INFO; } return GRUB_ERR_NONE; }