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

📄 grub-mkimage.c

📁 有助于了解操作系统如何启动之过程
💻 C
📖 第 1 页 / 共 3 页
字号:
  struct grub_pe32_fixup_block *fixup_block = 0;    for (i = 0, s = sections;       i < num_sections;       i++, s = (Elf32_Shdr *) ((char *) s + section_entsize))    if (s->sh_type == grub_cpu_to_le32 (SHT_REL))      {	Elf32_Rel *r;	Elf32_Word rtab_size, r_size, num_rs;	Elf32_Off rtab_offset;	Elf32_Addr section_address;	Elf32_Word j;		grub_util_info ("translating the relocation section %s",			strtab + grub_le_to_cpu32 (s->sh_name));				rtab_size = grub_le_to_cpu32 (s->sh_size);	r_size = grub_le_to_cpu32 (s->sh_entsize);	rtab_offset = grub_le_to_cpu32 (s->sh_offset);	num_rs = rtab_size / r_size;		section_address = section_addresses[grub_le_to_cpu32 (s->sh_info)];	for (j = 0, r = (Elf32_Rel *) ((char *) e + rtab_offset);	     j < num_rs;	     j++, r = (Elf32_Rel *) ((char *) r + r_size))	  {	    Elf32_Word info;	    Elf32_Addr offset;	    offset = grub_le_to_cpu32 (r->r_offset);	    info = grub_le_to_cpu32 (r->r_info);	    /* Necessary to relocate only absolute addresses.  */	    if (ELF32_R_TYPE (info) == R_386_32)	      {		Elf32_Addr addr;		addr = section_address + offset;		grub_util_info ("adding a relocation entry for 0x%x", addr);		current_address = add_fixup_entry (&fixup_block,						   GRUB_PE32_REL_BASED_HIGHLOW,						   addr, 0, current_address,						   out);	      }	  }      }  current_address = add_fixup_entry (&fixup_block, 0, 0, 1,				     current_address, out);  return current_address;}/* Create the header.  */static voidmake_header (FILE *out, Elf32_Addr text_address, Elf32_Addr data_address,	     Elf32_Addr mods_address, Elf32_Addr reloc_address,	     Elf32_Addr end_address, Elf32_Addr start_address){  struct grub_pe32_header header;  struct grub_pe32_coff_header *c;  struct grub_pe32_optional_header *o;  struct grub_pe32_section_table text_section, data_section;  struct grub_pe32_section_table mods_section, reloc_section;  /* The magic.  */  memset (&header, 0, sizeof (header));  memcpy (header.msdos_stub, stub, sizeof (header.msdos_stub));  memcpy (header.signature, "PE\0\0", sizeof (header.signature));  /* The COFF file header.  */  c = &header.coff_header;  c->machine = grub_cpu_to_le16 (GRUB_PE32_MACHINE_I386);  c->num_sections = grub_cpu_to_le16 (4);  c->time = grub_cpu_to_le32 (time (0));  c->optional_header_size = grub_cpu_to_le16 (sizeof (header.optional_header));  c->characteristics = grub_cpu_to_le16 (GRUB_PE32_EXECUTABLE_IMAGE					 | GRUB_PE32_LINE_NUMS_STRIPPED					 | GRUB_PE32_LOCAL_SYMS_STRIPPED					 | GRUB_PE32_32BIT_MACHINE);  /* The PE Optional header.  */  o = &header.optional_header;  o->magic = grub_cpu_to_le16 (GRUB_PE32_PE32_MAGIC);  o->code_size = grub_cpu_to_le32 (data_address - text_address);  o->data_size = grub_cpu_to_le32 (reloc_address - data_address);  o->bss_size = 0;  o->entry_addr = grub_cpu_to_le32 (start_address);  o->code_base = grub_cpu_to_le32 (text_address);  o->data_base = grub_cpu_to_le32 (data_address);  o->image_base = 0;  o->section_alignment = grub_cpu_to_le32 (GRUB_PE32_SECTION_ALIGNMENT);  o->file_alignment = grub_cpu_to_le32 (GRUB_PE32_FILE_ALIGNMENT);  o->image_size = grub_cpu_to_le32 (end_address);  o->header_size = grub_cpu_to_le32 (text_address);  o->subsystem = grub_cpu_to_le16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION);    /* Do these really matter? */  o->stack_reserve_size = grub_cpu_to_le32 (0x10000);  o->stack_commit_size = grub_cpu_to_le32 (0x10000);  o->heap_reserve_size = grub_cpu_to_le32 (0x10000);  o->heap_commit_size = grub_cpu_to_le32 (0x10000);  o->num_data_directories = grub_cpu_to_le32 (GRUB_PE32_NUM_DATA_DIRECTORIES);    o->base_relocation_table.rva = grub_cpu_to_le32 (reloc_address);  o->base_relocation_table.size = grub_cpu_to_le32 (end_address						    - reloc_address);  /* The sections.  */  memset (&text_section, 0, sizeof (text_section));  strcpy (text_section.name, ".text");  text_section.virtual_size = grub_cpu_to_le32 (data_address - text_address);  text_section.virtual_address = grub_cpu_to_le32 (text_address);  text_section.raw_data_size = grub_cpu_to_le32 (data_address - text_address);  text_section.raw_data_offset = grub_cpu_to_le32 (text_address);  text_section.characteristics = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_CODE						   | GRUB_PE32_SCN_MEM_EXECUTE						   | GRUB_PE32_SCN_MEM_READ);  memset (&data_section, 0, sizeof (data_section));  strcpy (data_section.name, ".data");  data_section.virtual_size = grub_cpu_to_le32 (mods_address - data_address);  data_section.virtual_address = grub_cpu_to_le32 (data_address);  data_section.raw_data_size = grub_cpu_to_le32 (mods_address - data_address);  data_section.raw_data_offset = grub_cpu_to_le32 (data_address);  data_section.characteristics    = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA			| GRUB_PE32_SCN_MEM_READ			| GRUB_PE32_SCN_MEM_WRITE);  memset (&mods_section, 0, sizeof (mods_section));  strcpy (mods_section.name, "mods");  mods_section.virtual_size = grub_cpu_to_le32 (reloc_address - mods_address);  mods_section.virtual_address = grub_cpu_to_le32 (mods_address);  mods_section.raw_data_size = grub_cpu_to_le32 (reloc_address - mods_address);  mods_section.raw_data_offset = grub_cpu_to_le32 (mods_address);  mods_section.characteristics    = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA			| GRUB_PE32_SCN_MEM_READ			| GRUB_PE32_SCN_MEM_WRITE);  memset (&reloc_section, 0, sizeof (reloc_section));  strcpy (reloc_section.name, ".reloc");  reloc_section.virtual_size = grub_cpu_to_le32 (end_address - reloc_address);  reloc_section.virtual_address = grub_cpu_to_le32 (reloc_address);  reloc_section.raw_data_size = grub_cpu_to_le32 (end_address - reloc_address);  reloc_section.raw_data_offset = grub_cpu_to_le32 (reloc_address);  reloc_section.characteristics    = grub_cpu_to_le32 (GRUB_PE32_SCN_CNT_INITIALIZED_DATA			| GRUB_PE32_SCN_MEM_DISCARDABLE			| GRUB_PE32_SCN_MEM_READ);  /* Write them out.  */  if (fseek (out, 0, SEEK_SET) < 0)    grub_util_error ("seek failed");  if (fwrite (&header, sizeof (header), 1, out) != 1      || fwrite (&text_section, sizeof (text_section), 1, out) != 1      || fwrite (&data_section, sizeof (data_section), 1, out) != 1      || fwrite (&mods_section, sizeof (mods_section), 1, out) != 1      || fwrite (&reloc_section, sizeof (reloc_section), 1, out) != 1)    grub_util_error ("write failed");}/* Convert an ELF relocatable object into an EFI Application (PE32).  */voidconvert_elf (const char *dir, char *prefix, FILE *out, char *mods[]){  char *kernel_image;  size_t kernel_size;  const char *strtab;  Elf32_Ehdr *e;  Elf32_Shdr *sections;  Elf32_Off section_offset;  Elf32_Half section_entsize;  Elf32_Half num_sections;  Elf32_Addr *section_addresses;  Elf32_Shdr *symtab_section;  Elf32_Addr start_address;  Elf32_Addr text_address, data_address, reloc_address, mods_address;  Elf32_Addr end_address;  /* Get the kernel image and check the format.  */  kernel_image = read_kernel_module (dir, prefix, &kernel_size);  e = (Elf32_Ehdr *) kernel_image;  if (! check_elf_header (e, kernel_size))    grub_util_error ("invalid ELF header");    section_offset = grub_cpu_to_le32 (e->e_shoff);  section_entsize = grub_cpu_to_le16 (e->e_shentsize);  num_sections = grub_cpu_to_le16 (e->e_shnum);  if (kernel_size < section_offset + section_entsize * num_sections)    grub_util_error ("invalid ELF format");  sections = (Elf32_Shdr *) (kernel_image + section_offset);  strtab = find_strtab (e, sections, section_entsize);  /* Relocate sections then symbols in the virtual address space.  */  section_addresses = locate_sections (sections, section_entsize,				       num_sections, strtab);    symtab_section = find_symtab_section (sections,					section_entsize, num_sections);  if (! symtab_section)    grub_util_error ("no symbol table");    start_address = relocate_symbols (e, sections, symtab_section,				    section_addresses, section_entsize,				    num_sections);  if (start_address == 0)    grub_util_error ("start symbol is not defined");  /* Resolve addresses in the virtual address space.  */  relocate_addresses (e, sections, section_addresses, section_entsize,		      num_sections, strtab);  /* Generate a PE32 image file. The strategy is to dump binary data first,     then fill up the header.  */  text_address = make_header_space (out);  data_address = write_text_sections (out, text_address, e, sections,				      section_entsize, num_sections,				      strtab);  mods_address = write_data_sections (out, data_address, e, sections,				      section_entsize, num_sections,				      strtab);  reloc_address = make_mods_section (out, mods_address, dir, mods);  end_address = make_reloc_section (out, reloc_address, e, section_addresses,				    sections, section_entsize, num_sections,				    strtab);  make_header (out, text_address, data_address, mods_address,	       reloc_address, end_address, start_address);  /* Clean up.  */  free (section_addresses);  free (kernel_image);}static struct option options[] =  {    {"directory", required_argument, 0, 'd'},    {"prefix", required_argument, 0, 'p'},    {"output", required_argument, 0, 'o'},    {"help", no_argument, 0, 'h'},    {"version", no_argument, 0, 'V'},    {"verbose", no_argument, 0, 'v'},    { 0, 0, 0, 0 }  };static voidusage (int status){  if (status)    fprintf (stderr, "Try ``grub-mkimage --help'' for more information.\n");  else    printf ("\Usage: grub-mkimage -o FILE [OPTION]... [MODULES]\n\\n\Make a bootable image of GRUB.\n\\n\-d, --directory=DIR     use images and modules under DIR [default=%s]\n\-p, --prefix=DIR        set grub_prefix directory [default=%s]\n\-o, --output=FILE       output a generated image to FILE\n\-h, --help              display this message and exit\n\-V, --version           print version information and exit\n\-v, --verbose           print verbose messages\n\\n\Report bugs to <%s>.\n\", GRUB_LIBDIR, DEFAULT_DIRECTORY, PACKAGE_BUGREPORT);  exit (status);}intmain (int argc, char *argv[]){  FILE *fp;  char *output = NULL;  char *dir = NULL;  char *prefix = NULL;  progname = "grub-mkimage";  while (1)    {      int c = getopt_long (argc, argv, "d:p:o:hVv", options, 0);      if (c == -1)	break;      switch (c)	{	  case 'd':	    if (dir)	      free (dir);	    dir = xstrdup (optarg);	    break;	  case 'h':	    usage (0);	    break;	  case 'o':	    if (output)	      free (output);	    output = xstrdup (optarg);	    break;	  case 'p':	    if (prefix)	      free (prefix);	    prefix = xstrdup (optarg);	    break;	  case 'V':	    printf ("grub-mkimage (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION);	    return 0;	  case 'v':	    verbosity++;	    break;	  default:	    usage (1);	    break;	}  }  if (! output)    usage (1);  fp = fopen (output, "wb");  if (! fp)    grub_util_error ("cannot open %s", output);  convert_elf (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind);  fclose (fp);  return 0;}

⌨️ 快捷键说明

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