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

📄 linux.c

📁 grub 1.95 linux 的bootloader 源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  if (grub_file_read (file, (char *) &lh, sizeof (lh)) != sizeof (lh))    {      grub_error (GRUB_ERR_READ_ERROR, "cannot read the linux header");      goto fail;    }  if (lh.boot_flag != grub_cpu_to_le16 (0xaa55))    {      grub_error (GRUB_ERR_BAD_OS, "invalid magic number");      goto fail;    }  if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)    {      grub_error (GRUB_ERR_BAD_OS, "too many setup sectors");      goto fail;    }  /* EFI support is quite new, so reject old versions.  */  if (lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)      || grub_le_to_cpu16 (lh.version) < 0x0203)    {      grub_error (GRUB_ERR_BAD_OS, "too old version");      goto fail;    }  /* I'm not sure how to support zImage on EFI.  */  if (! (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL))    {      grub_error (GRUB_ERR_BAD_OS, "zImage is not supported");      goto fail;    }  setup_sects = lh.setup_sects;    /* If SETUP_SECTS is not set, set it to the default (4).  */  if (! setup_sects)    setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;  real_size = setup_sects << GRUB_DISK_SECTOR_BITS;  prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;    if (! allocate_pages (real_size, prot_size))    goto fail;    /* XXX Linux assumes that only elilo can boot Linux on EFI!!!  */  lh.type_of_loader = 0x50;  lh.cl_magic = GRUB_LINUX_CL_MAGIC;  lh.cl_offset = GRUB_LINUX_CL_END_OFFSET;  lh.cmd_line_ptr = (char *) real_mode_mem + GRUB_LINUX_CL_OFFSET;  lh.ramdisk_image = 0;  lh.ramdisk_size = 0;  params = (struct linux_kernel_params *) &lh;  /* These are not needed to be precise, because Linux uses these values     only to raise an error when the decompression code cannot find good     space.  */  params->ext_mem = ((32 * 0x100000) >> 10);  params->alt_mem = ((32 * 0x100000) >> 10);    params->video_cursor_x = grub_efi_system_table->con_out->mode->cursor_column;  params->video_cursor_y = grub_efi_system_table->con_out->mode->cursor_row;  params->video_page = 0; /* ??? */  params->video_mode = grub_efi_system_table->con_out->mode->mode;  params->video_width = (grub_getwh () >> 8);  params->video_ega_bx = 0;  params->video_height = (grub_getwh () & 0xff);  params->have_vga = 0;  params->font_size = 16; /* XXX */  /* No VBE on EFI.  */  params->lfb_width = 0;  params->lfb_height = 0;  params->lfb_depth = 0;  params->lfb_base = 0;  params->lfb_size = 0;  params->lfb_line_len = 0;  params->red_mask_size = 0;  params->red_field_pos = 0;  params->green_mask_size = 0;  params->green_field_pos = 0;  params->blue_mask_size = 0;  params->blue_field_pos = 0;  params->reserved_mask_size = 0;  params->reserved_field_pos = 0;  params->vesapm_segment = 0;  params->vesapm_offset = 0;  params->lfb_pages = 0;  params->vesa_attrib = 0;  /* No APM on EFI.  */  params->apm_version = 0;  params->apm_code_segment = 0;  params->apm_entry = 0;  params->apm_16bit_code_segment = 0;  params->apm_data_segment = 0;  params->apm_flags = 0;  params->apm_code_len = 0;  params->apm_data_len = 0;  /* XXX is there any way to use SpeedStep on EFI?  */  params->ist_signature = 0;  params->ist_command = 0;  params->ist_event = 0;  params->ist_perf_level = 0;  /* Let the kernel probe the information.  */  grub_memset (params->hd0_drive_info, 0, sizeof (params->hd0_drive_info));  grub_memset (params->hd1_drive_info, 0, sizeof (params->hd1_drive_info));  /* No MCA on EFI.  */  params->rom_config_len = 0;  params->efi_signature = GRUB_LINUX_EFI_SIGNATURE; /* XXX not used */  params->efi_system_table = (grub_addr_t) grub_efi_system_table;  /* The other EFI parameters are filled when booting.  */  /* No need to fake the BIOS's memory map.  */  params->mmap_size = 0;  /* Let the kernel probe the information.  */  params->ps_mouse = 0;  /* Clear padding for future compatibility.  */  grub_memset (params->padding1, 0, sizeof (params->padding1));  grub_memset (params->padding2, 0, sizeof (params->padding2));  grub_memset (params->padding3, 0, sizeof (params->padding3));  grub_memset (params->padding4, 0, sizeof (params->padding4));  grub_memset (params->padding5, 0, sizeof (params->padding5));  grub_memset (params->padding6, 0, sizeof (params->padding6));  grub_memset (params->padding7, 0, sizeof (params->padding7));  grub_memset (params->padding8, 0, sizeof (params->padding8));  grub_memset (params->padding9, 0, sizeof (params->padding9));    /* Put the real mode code at the real location.  */  grub_memmove (real_mode_mem, &lh, sizeof (lh));  len = real_size + GRUB_DISK_SECTOR_SIZE - 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");      goto fail;    }  /* XXX there is no way to know if the kernel really supports EFI.  */  grub_printf ("   [Linux-EFI, setup=0x%x, size=0x%x]\n",	       real_size, prot_size);  /* Detect explicitly specified memory size, if any.  */  linux_mem_size = 0;  for (i = 1; i < argc; i++)    if (grub_memcmp (argv[i], "mem=", 4) == 0)      {	char *val = argv[i] + 4;	  	linux_mem_size = grub_strtoul (val, &val, 0);		if (grub_errno)	  {	    grub_errno = GRUB_ERR_NONE;	    linux_mem_size = 0;	  }	else	  {	    int shift = 0;	    	    switch (grub_tolower (val[0]))	      {	      case 'g':		shift += 10;	      case 'm':		shift += 10;	      case 'k':		shift += 10;	      default:		break;	      }	    /* Check an overflow.  */	    if (linux_mem_size > (~0UL >> shift))	      linux_mem_size = 0;	    else	      linux_mem_size <<= shift;	  }      }  /* Specify the boot file.  */  dest = grub_stpcpy ((char *) real_mode_mem + GRUB_LINUX_CL_OFFSET,		      "BOOT_IMAGE=");  dest = grub_stpcpy (dest, argv[0]);    /* Copy kernel parameters.  */  for (i = 1;       i < argc	 && dest + grub_strlen (argv[i]) + 1 < ((char *) real_mode_mem						+ GRUB_LINUX_CL_END_OFFSET);       i++)    {      *dest++ = ' ';      dest = grub_stpcpy (dest, argv[i]);    }  len = prot_size;  if (grub_file_read (file, (char *) GRUB_LINUX_BZIMAGE_ADDR, len) != len)    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);      loaded = 1;    } fail:    if (file)    grub_file_close (file);  if (grub_errno != GRUB_ERR_NONE)    {      grub_dl_unref (my_mod);      loaded = 0;    }}voidgrub_rescue_cmd_initrd (int argc, char *argv[]){  grub_file_t file = 0;  grub_ssize_t size;  grub_addr_t addr_min, addr_max;  grub_addr_t addr;  grub_efi_uintn_t mmap_size;  grub_efi_memory_descriptor_t *desc;  grub_efi_uintn_t desc_size;  struct linux_kernel_header *lh;    if (argc == 0)    {      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.");      goto fail;    }  file = grub_file_open (argv[0]);  if (! file)    goto fail;  size = grub_file_size (file);  initrd_pages = (page_align (size) >> 12);  lh = (struct linux_kernel_header *) real_mode_mem;    addr_max = grub_cpu_to_le32 (lh->initrd_addr_max);  if (linux_mem_size != 0 && linux_mem_size < addr_max)    addr_max = linux_mem_size;    /* Linux 2.3.xx has a bug in the memory range check, so avoid     the last page.     Linux 2.2.xx has a bug in the memory range check, which is     worse than that of Linux 2.3.xx, so avoid the last 64kb.  */  addr_max -= 0x10000;  /* Usually, the compression ratio is about 50%.  */  addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12);    /* Find the highest address to put the initrd.  */  mmap_size = find_mmap_size ();  if (grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0) <= 0)    grub_fatal ("cannot get memory map");  addr = 0;  for (desc = mmap_buf;       desc < NEXT_MEMORY_DESCRIPTOR (mmap_buf, mmap_size);       desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))    {      if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY	  && desc->physical_start >= addr_min	  && desc->physical_start + size < addr_max	  && desc->num_pages >= initrd_pages)	{	  grub_efi_physical_address_t physical_end;	  	  physical_end = desc->physical_start + (desc->num_pages << 12);	  if (physical_end > addr_max)	    physical_end = addr_max;	  if (physical_end > addr)	    addr = physical_end - page_align (size);	}    }  if (addr == 0)    {      grub_error (GRUB_ERR_OUT_OF_MEMORY, "no free pages available");      goto fail;    }    initrd_mem = grub_efi_allocate_pages (addr, initrd_pages);  if (! initrd_mem)    grub_fatal ("cannot allocate pages");    if (grub_file_read (file, initrd_mem, size) != size)    {      grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");      goto fail;    }  grub_printf ("   [Initrd, addr=0x%x, size=0x%x]\n",	       addr, size);    lh->ramdisk_image = addr;  lh->ramdisk_size = size;  lh->root_dev = 0x0100; /* XXX */   fail:  if (file)    grub_file_close (file);}GRUB_MOD_INIT(linux){  grub_rescue_register_command ("linux",				grub_rescue_cmd_linux,				"load linux");  grub_rescue_register_command ("initrd",				grub_rescue_cmd_initrd,				"load initrd");  my_mod = mod;}GRUB_MOD_FINI(linux){  grub_rescue_unregister_command ("linux");  grub_rescue_unregister_command ("initrd");}

⌨️ 快捷键说明

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