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

📄 grub-mkimage.c

📁 grub 1.95 linux 的bootloader 源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	Elf32_Word size = grub_le_to_cpu32 (s->sh_size);	const char *name = strtab + grub_le_to_cpu32 (s->sh_name);		if (align)	  {	    addr = align_address (current_address, align);	    if (current_address != addr)	      {		grub_util_info ("padding %d bytes for the ELF section alignment",				addr - current_address);		write_padding (out, addr - current_address);		current_address = addr;	      }	  }		grub_util_info ("writing the text section %s at 0x%x",			name, current_address);		if (fwrite ((char *) e + offset, size, 1, out) != 1)	  grub_util_error ("write failed");		current_address += size;      }  addr = align_pe32_section (current_address);  if (addr != current_address)    {      grub_util_info ("padding %d bytes for the PE32 section alignment",		      addr - current_address);      write_padding (out, addr - current_address);    }    return addr;}/* Write data sections.  */static Elf32_Addrwrite_data_sections (FILE *out, Elf32_Addr current_address,		     Elf32_Ehdr *e, Elf32_Shdr *sections,		     Elf32_Half section_entsize, Elf32_Half num_sections,		     const char *strtab){  Elf32_Half i;  Elf32_Shdr *s;  Elf32_Addr addr;    for (i = 0, s = sections;       i < num_sections;       i++, s = (Elf32_Shdr *) ((char *) s + section_entsize))    if (is_data_section (s))      {	Elf32_Word align = grub_le_to_cpu32 (s->sh_addralign);	Elf32_Off offset = grub_le_to_cpu32 (s->sh_offset);	Elf32_Word size = grub_le_to_cpu32 (s->sh_size);	const char *name = strtab + grub_le_to_cpu32 (s->sh_name);		if (align)	  {	    addr = align_address (current_address, align);	    if (current_address != addr)	      {		grub_util_info ("padding %d bytes for the ELF section alignment",				addr - current_address);		write_padding (out, addr - current_address);		current_address = addr;	      }	  }		grub_util_info ("writing the data section %s at 0x%x",			name, current_address);		if (s->sh_type == grub_cpu_to_le32 (SHT_NOBITS))	  write_padding (out, size);	else	  if (fwrite ((char *) e + offset, size, 1, out) != 1)	    grub_util_error ("write failed");		current_address += size;      }    addr = align_pe32_section (current_address);  if (addr != current_address)    {      grub_util_info ("padding %d bytes for the PE32 section alignment",		      addr - current_address);      write_padding (out, addr - current_address);    }    return addr;}/* Write modules.  */static Elf32_Addrmake_mods_section (FILE *out, Elf32_Addr current_address,		   const char *dir, char *mods[]){  struct grub_util_path_list *path_list;  grub_size_t total_module_size;  struct grub_util_path_list *p;  struct grub_module_info modinfo;  Elf32_Addr addr;  path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods);    total_module_size = sizeof (struct grub_module_info);  for (p = path_list; p; p = p->next)    {      total_module_size += (grub_util_get_image_size (p->name)			    + sizeof (struct grub_module_header));    }  grub_util_info ("the total module size is 0x%x", total_module_size);  modinfo.magic = grub_cpu_to_le32 (GRUB_MODULE_MAGIC);  modinfo.offset = grub_cpu_to_le32 (sizeof (modinfo));  modinfo.size = grub_cpu_to_le32 (total_module_size);  if (fwrite (&modinfo, sizeof (modinfo), 1, out) != 1)    grub_util_error ("write failed");  for (p = path_list; p; p = p->next)    {      struct grub_module_header header;      size_t mod_size;      char *mod_image;            grub_util_info ("adding module %s", p->name);            mod_size = grub_util_get_image_size (p->name);      header.offset = grub_cpu_to_le32 (sizeof (header));      header.size = grub_cpu_to_le32 (mod_size + sizeof (header));            mod_image = grub_util_read_image (p->name);      if (fwrite (&header, sizeof (header), 1, out) != 1	  || fwrite (mod_image, mod_size, 1, out) != 1)	grub_util_error ("write failed");      free (mod_image);    }    for (p = path_list; p; )    {      struct grub_util_path_list *q;      q = p->next;      free (p);      p = q;    }        current_address += total_module_size;    addr = align_pe32_section (current_address);  if (addr != current_address)    {      grub_util_info ("padding %d bytes for the PE32 section alignment",		      addr - current_address);      write_padding (out, addr - current_address);    }  return addr;}/* Make a .reloc section.  */static Elf32_Addrmake_reloc_section (FILE *out, Elf32_Addr current_address, Elf32_Ehdr *e, 		    Elf32_Addr *section_addresses, Elf32_Shdr *sections,		    Elf32_Half section_entsize, Elf32_Half num_sections,		    const char *strtab){  Elf32_Half i;  Elf32_Shdr *s;  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, 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, &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'},    {"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\-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, PACKAGE_BUGREPORT);  exit (status);}intmain (int argc, char *argv[]){  FILE *fp;  char *output = NULL;  char *dir = NULL;  progname = "grub-mkimage";  while (1)    {      int c = getopt_long (argc, argv, "d: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 '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, fp, argv + optind);  fclose (fp);  return 0;}

⌨️ 快捷键说明

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