⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vbe.c

📁 grub 1.95 linux 的bootloader 源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* *  GRUB  --  GRand Unified Bootloader *  Copyright (C) 2005,2006  Free Software Foundation, Inc. * *  This program 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 2 of the License, or *  (at your option) any later version. * *  This program 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 this program; if not, write to the Free Software *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <grub/err.h>#include <grub/machine/memory.h>#include <grub/machine/vbe.h>#include <grub/machine/vbeblit.h>#include <grub/machine/vbefill.h>#include <grub/machine/vbeutil.h>#include <grub/types.h>#include <grub/dl.h>#include <grub/misc.h>#include <grub/font.h>#include <grub/mm.h>#include <grub/video.h>#include <grub/bitmap.h>/* Specify "standard" VGA palette, some video cards may   need this and this will also be used when using RGB modes.  */static struct grub_vbe_palette_data vga_colors[16] =  {    // {B, G, R, A}    {0x00, 0x00, 0x00, 0x00}, // 0 = black    {0xA8, 0x00, 0x00, 0x00}, // 1 = blue    {0x00, 0xA8, 0x00, 0x00}, // 2 = green    {0xA8, 0xA8, 0x00, 0x00}, // 3 = cyan    {0x00, 0x00, 0xA8, 0x00}, // 4 = red    {0xA8, 0x00, 0xA8, 0x00}, // 5 = magenta    {0x00, 0x54, 0xA8, 0x00}, // 6 = brown    {0xA8, 0xA8, 0xA8, 0x00}, // 7 = ligth gray    {0x54, 0x54, 0x54, 0x00}, // 8 = dark gray    {0xFE, 0x54, 0x54, 0x00}, // 9 = bright blue    {0x54, 0xFE, 0x54, 0x00}, // 10 = bright green    {0xFE, 0xFE, 0x54, 0x00}, // 11 = bright cyan    {0x54, 0x54, 0xFE, 0x00}, // 12 = bright red    {0xFE, 0x54, 0xFE, 0x00}, // 13 = bright magenta    {0x54, 0xFE, 0xFE, 0x00}, // 14 = yellow    {0xFE, 0xFE, 0xFE, 0x00}  // 15 = white  };static int vbe_detected = -1;static struct grub_vbe_info_block controller_info;static struct grub_vbe_mode_info_block active_mode_info;static struct{  struct grub_video_render_target render_target;  unsigned int bytes_per_scan_line;  unsigned int bytes_per_pixel;  grub_uint32_t active_mode;  grub_uint8_t *ptr;  int index_color_mode;  struct grub_video_palette_data palette[256];} framebuffer;static struct grub_video_render_target *render_target;static grub_uint32_t initial_mode;static grub_uint32_t mode_in_use = 0x55aa;static grub_uint16_t *mode_list;static void *real2pm (grub_vbe_farptr_t ptr){  return (void *) ((((unsigned long) ptr & 0xFFFF0000) >> 12UL)                   + ((unsigned long) ptr & 0x0000FFFF));}grub_err_tgrub_vbe_probe (struct grub_vbe_info_block *info_block){  struct grub_vbe_info_block *vbe_ib;  grub_vbe_status_t status;  /* Clear caller's controller info block.  */  if (info_block)    grub_memset (info_block, 0, sizeof (*info_block));  /* Do not probe more than one time, if not necessary.  */  if (vbe_detected == -1 || info_block)    {      /* Clear old copy of controller info block.  */      grub_memset (&controller_info, 0, sizeof (controller_info));      /* Mark VESA BIOS extension as undetected.  */      vbe_detected = 0;      /* Use low memory scratch area as temporary storage         for VESA BIOS call.  */      vbe_ib = (struct grub_vbe_info_block *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;      /* Prepare info block.  */      grub_memset (vbe_ib, 0, sizeof (*vbe_ib));      vbe_ib->signature[0] = 'V';      vbe_ib->signature[1] = 'B';      vbe_ib->signature[2] = 'E';      vbe_ib->signature[3] = '2';      /* Try to get controller info block.  */      status = grub_vbe_bios_get_controller_info (vbe_ib);      if (status == 0x004F)        {          /* Copy it for later usage.  */          grub_memcpy (&controller_info, vbe_ib, sizeof (controller_info));          /* Mark VESA BIOS extension as detected.  */          vbe_detected = 1;        }    }  if (! vbe_detected)    return grub_error (GRUB_ERR_BAD_DEVICE, "VESA BIOS Extension not found");  /* Make copy of controller info block to caller.  */  if (info_block)    grub_memcpy (info_block, &controller_info, sizeof (*info_block));  return GRUB_ERR_NONE;}grub_err_tgrub_vbe_set_video_mode (grub_uint32_t mode,                         struct grub_vbe_mode_info_block *mode_info){  grub_vbe_status_t status;  grub_uint32_t old_mode;  /* Make sure that VBE is supported.  */  grub_vbe_probe (0);  if (grub_errno != GRUB_ERR_NONE)    return grub_errno;  /* Try to get mode info.  */  grub_vbe_get_video_mode_info (mode, &active_mode_info);  if (grub_errno != GRUB_ERR_NONE)    return grub_errno;  /* For all VESA BIOS modes, force linear frame buffer.  */  if (mode >= 0x100)    {      /* We only want linear frame buffer modes.  */      mode |= 1 << 14;      /* Determine frame buffer pixel format.  */      switch (active_mode_info.memory_model)        {        case GRUB_VBE_MEMORY_MODEL_PACKED_PIXEL:          framebuffer.index_color_mode = 1;          break;        case GRUB_VBE_MEMORY_MODEL_DIRECT_COLOR:          framebuffer.index_color_mode = 0;          break;        default:          return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,                             "unsupported pixel format 0x%x",                             active_mode_info.memory_model);        }    }  /* Get current mode.  */  grub_vbe_get_video_mode (&old_mode);  if (grub_errno != GRUB_ERR_NONE)    return grub_errno;  /* Try to set video mode.  */  status = grub_vbe_bios_set_mode (mode, 0);  if (status != GRUB_VBE_STATUS_OK)    return grub_error (GRUB_ERR_BAD_DEVICE, "cannot set VBE mode %x", mode);  /* Save information for later usage.  */  framebuffer.active_mode = mode;  if (mode < 0x100)    {      /* If this is not a VESA mode, guess address.  */      framebuffer.ptr = (grub_uint8_t *) 0xA0000;      framebuffer.index_color_mode = 1;    }  else    {      framebuffer.ptr = (grub_uint8_t *) active_mode_info.phys_base_addr;      if (controller_info.version >= 0x300)        framebuffer.bytes_per_scan_line = active_mode_info.lin_bytes_per_scan_line;      else        framebuffer.bytes_per_scan_line = active_mode_info.bytes_per_scan_line;    }  /* Calculate bytes_per_pixel value.  */  switch(active_mode_info.bits_per_pixel)    {    case 32: framebuffer.bytes_per_pixel = 4; break;    case 24: framebuffer.bytes_per_pixel = 3; break;    case 16: framebuffer.bytes_per_pixel = 2; break;    case 15: framebuffer.bytes_per_pixel = 2; break;    case 8: framebuffer.bytes_per_pixel = 1; break;    default:      grub_vbe_bios_set_mode (old_mode, 0);      return grub_error (GRUB_ERR_BAD_DEVICE,                          "cannot set VBE mode %x",                         mode);      break;    }  /* If video mode is in indexed color, setup default VGA palette.  */  if (framebuffer.index_color_mode)    {      struct grub_vbe_palette_data *palette        = (struct grub_vbe_palette_data *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;      /* Make sure that the BIOS can reach the palette.  */      grub_memcpy (palette, vga_colors, sizeof (vga_colors));      status = grub_vbe_bios_set_palette_data (sizeof (vga_colors)                                                / sizeof (struct grub_vbe_palette_data),                                                0,                                                palette);      /* Just ignore the status.  */    }  /* Copy mode info for caller.  */  if (mode_info)    grub_memcpy (mode_info, &active_mode_info, sizeof (*mode_info));  return GRUB_ERR_NONE;}grub_err_tgrub_vbe_get_video_mode (grub_uint32_t *mode){  grub_vbe_status_t status;  /* Make sure that VBE is supported.  */  grub_vbe_probe (0);  if (grub_errno != GRUB_ERR_NONE)    return grub_errno;  /* Try to query current mode from VESA BIOS.  */  status = grub_vbe_bios_get_mode (mode);  if (status != GRUB_VBE_STATUS_OK)    return grub_error (GRUB_ERR_BAD_DEVICE, "cannot get current VBE mode");  return GRUB_ERR_NONE;}grub_err_tgrub_vbe_get_video_mode_info (grub_uint32_t mode,                              struct grub_vbe_mode_info_block *mode_info){  struct grub_vbe_mode_info_block *mi_tmp    = (struct grub_vbe_mode_info_block *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;  grub_vbe_status_t status;  /* Make sure that VBE is supported.  */  grub_vbe_probe (0);  if (grub_errno != GRUB_ERR_NONE)    return grub_errno;  /* If mode is not VESA mode, skip mode info query.  */  if (mode >= 0x100)    {      /* Try to get mode info from VESA BIOS.  */      status = grub_vbe_bios_get_mode_info (mode, mi_tmp);      if (status != GRUB_VBE_STATUS_OK)        return grub_error (GRUB_ERR_BAD_DEVICE,                           "cannot get information on the mode %x", mode);      /* Make copy of mode info block.  */      grub_memcpy (mode_info, mi_tmp, sizeof (*mode_info));    }  else    /* Just clear mode info block if it isn't a VESA mode.  */    grub_memset (mode_info, 0, sizeof (*mode_info));  return GRUB_ERR_NONE;}grub_uint8_t *grub_video_vbe_get_video_ptr (struct grub_video_i386_vbeblit_info *source,                              grub_uint32_t x, grub_uint32_t y){  grub_uint8_t *ptr = 0;  switch (source->mode_info->bpp)    {    case 32:      ptr = (grub_uint8_t *)source->data            + y * source->mode_info->pitch            + x * 4;      break;    case 24:      ptr = (grub_uint8_t *)source->data            + y * source->mode_info->pitch            + x * 3;      break;    case 16:    case 15:      ptr = (grub_uint8_t *)source->data            + y * source->mode_info->pitch            + x * 2;      break;    case 8:      ptr = (grub_uint8_t *)source->data            + y * source->mode_info->pitch            + x;      break;    }  return ptr;}static grub_err_tgrub_video_vbe_init (void){  grub_uint16_t *rm_mode_list;  grub_uint16_t *p;  grub_size_t mode_list_size;  struct grub_vbe_info_block info_block;  /* Check if there is adapter present.     Firmware note: There has been a report that some cards store video mode     list in temporary memory.  So we must first use vbe probe to get     refreshed information to receive valid pointers and data, and then     copy this information to somewhere safe.  */  grub_vbe_probe (&info_block);  if (grub_errno != GRUB_ERR_NONE)    return grub_errno;  /* Copy modelist to local memory.  */  p = rm_mode_list = real2pm (info_block.video_mode_ptr);  while(*p++ != 0xFFFF)    ;  mode_list_size = (grub_addr_t) p - (grub_addr_t) rm_mode_list;  mode_list = grub_malloc (mode_list_size);  if (! mode_list)    return grub_errno;  grub_memcpy (mode_list, rm_mode_list, mode_list_size);  /* Adapter could be found, figure out initial video mode.  */  grub_vbe_get_video_mode (&initial_mode);  if (grub_errno != GRUB_ERR_NONE)    {      /* Free allocated resources.  */      grub_free (mode_list);      mode_list = 0;      return grub_errno;    }  /* Reset frame buffer and render target variables.  */  grub_memset (&framebuffer, 0, sizeof(framebuffer));  render_target = &framebuffer.render_target;  return GRUB_ERR_NONE;}static grub_err_tgrub_video_vbe_fini (void){  grub_vbe_status_t status;  /* Restore old video mode.  */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -