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

📄 boot.c

📁 i386的bootloader源码grub
💻 C
📖 第 1 页 / 共 2 页
字号:
		printf (", C");	      printf (", data=0x%x", data_len);	      if ((grub_read ((char *) RAW_ADDR (cur_addr), data_len)		   != data_len)		  && !errnum)		errnum = ERR_EXEC_FORMAT;	      cur_addr += data_len;	    }	  if (!errnum)	    {	      memset ((char *) RAW_ADDR (cur_addr), 0, bss_len);	      cur_addr += bss_len;	      printf (", bss=0x%x", bss_len);	    }	}      else if (!errnum)	errnum = ERR_EXEC_FORMAT;      if (!errnum && pu.aout->a_syms	  && pu.aout->a_syms < (filemax - filepos))	{	  int symtab_err, orig_addr = cur_addr;	  /* we should align to a 4K boundary here for good measure */	  if (align_4k)	    cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000;	  mbi.syms.a.addr = cur_addr;	  *((int *) RAW_ADDR (cur_addr)) = pu.aout->a_syms;	  cur_addr += sizeof (int);	  	  printf (", symtab=0x%x", pu.aout->a_syms);	  if (grub_read ((char *) RAW_ADDR (cur_addr), pu.aout->a_syms)	      == pu.aout->a_syms)	    {	      cur_addr += pu.aout->a_syms;	      mbi.syms.a.tabsize = pu.aout->a_syms;	      if (grub_read ((char *) &i, sizeof (int)) == sizeof (int))		{		  *((int *) RAW_ADDR (cur_addr)) = i;		  cur_addr += sizeof (int);		  mbi.syms.a.strsize = i;		  i -= sizeof (int);		  printf (", strtab=0x%x", i);		  symtab_err = (grub_read ((char *) RAW_ADDR (cur_addr), i)				!= i);		  cur_addr += i;		}	      else		symtab_err = 1;	    }	  else	    symtab_err = 1;	  if (symtab_err)	    {	      printf ("(bad)");	      cur_addr = orig_addr;	      mbi.syms.a.tabsize = 0;	      mbi.syms.a.strsize = 0;	      mbi.syms.a.addr = 0;	    }	  else	    mbi.flags |= MB_INFO_AOUT_SYMS;	}    }  else    /* ELF executable */    {      unsigned loaded = 0, memaddr, memsiz, filesiz;      Elf32_Phdr *phdr;      /* reset this to zero for now */      cur_addr = 0;      /* scan for program segments */      for (i = 0; i < pu.elf->e_phnum; i++)	{	  phdr = (Elf32_Phdr *)	    (pu.elf->e_phoff + ((int) buffer)	     + (pu.elf->e_phentsize * i));	  if (phdr->p_type == PT_LOAD)	    {	      /* offset into file */	      grub_seek (phdr->p_offset);	      filesiz = phdr->p_filesz;	      	      if (type == KERNEL_TYPE_FREEBSD || type == KERNEL_TYPE_NETBSD)		memaddr = RAW_ADDR (phdr->p_paddr & 0xFFFFFF);	      else		memaddr = RAW_ADDR (phdr->p_paddr);	      	      memsiz = phdr->p_memsz;	      if (memaddr < RAW_ADDR (0x100000))		errnum = ERR_BELOW_1MB;	      /* If the memory range contains the entry address, get the		 physical address here.  */	      if (type == KERNEL_TYPE_MULTIBOOT		  && (unsigned) entry_addr >= phdr->p_vaddr		  && (unsigned) entry_addr < phdr->p_vaddr + memsiz)		real_entry_addr = (entry_func) ((unsigned) entry_addr						+ memaddr - phdr->p_vaddr);			      /* make sure we only load what we're supposed to! */	      if (filesiz > memsiz)		filesiz = memsiz;	      /* mark memory as used */	      if (cur_addr < memaddr + memsiz)		cur_addr = memaddr + memsiz;	      printf (", <0x%x:0x%x:0x%x>", memaddr, filesiz,		      memsiz - filesiz);	      /* increment number of segments */	      loaded++;	      /* load the segment */	      if (memcheck (memaddr, memsiz)		  && grub_read ((char *) memaddr, filesiz) == filesiz)		{		  if (memsiz > filesiz)		    memset ((char *) (memaddr + filesiz), 0, memsiz - filesiz);		}	      else		break;	    }	}      if (! errnum)	{	  if (! loaded)	    errnum = ERR_EXEC_FORMAT;	  else	    {	      /* Load ELF symbols.  */	      Elf32_Shdr *shdr = NULL;	      int tab_size, sec_size;	      int symtab_err = 0;	      mbi.syms.e.num = pu.elf->e_shnum;	      mbi.syms.e.size = pu.elf->e_shentsize;	      mbi.syms.e.shndx = pu.elf->e_shstrndx;	      	      /* We should align to a 4K boundary here for good measure.  */	      if (align_4k)		cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000;	      	      tab_size = pu.elf->e_shentsize * pu.elf->e_shnum;	      	      grub_seek (pu.elf->e_shoff);	      if (grub_read ((char *) RAW_ADDR (cur_addr), tab_size)		  == tab_size)		{		  mbi.syms.e.addr = cur_addr;		  shdr = (Elf32_Shdr *) mbi.syms.e.addr;		  cur_addr += tab_size;		  		  printf (", shtab=0x%x", cur_addr);  		  		  for (i = 0; i < mbi.syms.e.num; i++)		    {		      /* This section is a loaded section,			 so we don't care.  */		      if (shdr[i].sh_addr != 0)			continue;		      		      /* This section is empty, so we don't care.  */		      if (shdr[i].sh_size == 0)			continue;		      		      /* Align the section to a sh_addralign bits boundary.  */		      cur_addr = ((cur_addr + shdr[i].sh_addralign) & 				  - (int) shdr[i].sh_addralign);		      		      grub_seek (shdr[i].sh_offset);		      		      sec_size = shdr[i].sh_size;		      if (! (memcheck (cur_addr, sec_size)			     && (grub_read ((char *) RAW_ADDR (cur_addr),					    sec_size)				 == sec_size)))			{			  symtab_err = 1;			  break;			}		      		      shdr[i].sh_addr = cur_addr;		      cur_addr += sec_size;		    }		}	      else 		symtab_err = 1;	      	      if (mbi.syms.e.addr < RAW_ADDR(0x10000))		symtab_err = 1;	      	      if (symtab_err) 		{		  printf ("(bad)");		  mbi.syms.e.num = 0;		  mbi.syms.e.size = 0;		  mbi.syms.e.addr = 0;		  mbi.syms.e.shndx = 0;		  cur_addr = 0;		}	      else		mbi.flags |= MB_INFO_ELF_SHDR;	    }	}    }  if (! errnum)    {      grub_printf (", entry=0x%x]\n", (unsigned) entry_addr);            /* If the entry address is physically different from that of the ELF	 header, correct it here.  */      if (real_entry_addr)	entry_addr = real_entry_addr;    }  else    {      putchar ('\n');      type = KERNEL_TYPE_NONE;    }  grub_close ();  /* Sanity check.  */  if (suggested_type != KERNEL_TYPE_NONE && suggested_type != type)    {      errnum = ERR_EXEC_FORMAT;      return KERNEL_TYPE_NONE;    }    return type;}intload_module (char *module, char *arg){  int len;  /* if we are supposed to load on 4K boundaries */  cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000;  if (!grub_open (module))    return 0;  len = grub_read ((char *) cur_addr, -1);  if (! len)    {      grub_close ();      return 0;    }  printf ("   [Multiboot-module @ 0x%x, 0x%x bytes]\n", cur_addr, len);  /* these two simply need to be set if any modules are loaded at all */  mbi.flags |= MB_INFO_MODS;  mbi.mods_addr = (int) mll;  mll[mbi.mods_count].cmdline = (int) arg;  mll[mbi.mods_count].mod_start = cur_addr;  cur_addr += len;  mll[mbi.mods_count].mod_end = cur_addr;  mll[mbi.mods_count].pad = 0;  /* increment number of modules included */  mbi.mods_count++;  grub_close ();  return 1;}intload_initrd (char *initrd){  int len;  unsigned long moveto;  unsigned long max_addr;  struct linux_kernel_header *lh    = (struct linux_kernel_header *) (cur_addr - LINUX_SETUP_MOVE_SIZE);  #ifndef NO_DECOMPRESSION  no_decompression = 1;#endif    if (! grub_open (initrd))    goto fail;  len = grub_read ((char *) cur_addr, -1);  if (! len)    {      grub_close ();      goto fail;    }  if (linux_mem_size)    moveto = linux_mem_size;  else    moveto = (mbi.mem_upper + 0x400) << 10;    moveto = (moveto - len) & 0xfffff000;  max_addr = (lh->header == LINUX_MAGIC_SIGNATURE && lh->version >= 0x0203	      ? lh->initrd_addr_max : LINUX_INITRD_MAX_ADDRESS);  if (moveto + len >= max_addr)    moveto = (max_addr - len) & 0xfffff000;    /* XXX: Linux 2.3.xx has a bug in the memory range check, so avoid     the last page.     XXX: 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. *sigh*  */  moveto -= 0x10000;  memmove ((void *) RAW_ADDR (moveto), (void *) cur_addr, len);  printf ("   [Linux-initrd @ 0x%x, 0x%x bytes]\n", moveto, len);  /* FIXME: Should check if the kernel supports INITRD.  */  lh->ramdisk_image = RAW_ADDR (moveto);  lh->ramdisk_size = len;  grub_close (); fail:  #ifndef NO_DECOMPRESSION  no_decompression = 0;#endif  return ! errnum;}#ifdef GRUB_UTIL/* Dummy function to fake the *BSD boot.  */static voidbsd_boot_entry (int flags, int bootdev, int sym_start, int sym_end,		int mem_upper, int mem_lower){  stop ();}#endif/* *  All "*_boot" commands depend on the images being loaded into memory *  correctly, the variables in this file being set up correctly, and *  the root partition being set in the 'saved_drive' and 'saved_partition' *  variables. */voidbsd_boot (kernel_t type, int bootdev, char *arg){  char *str;  int clval = 0, i;  struct bootinfo bi;#ifdef GRUB_UTIL  entry_addr = (entry_func) bsd_boot_entry;#else  stop_floppy ();#endif  while (*(++arg) && *arg != ' ');  str = arg;  while (*str)    {      if (*str == '-')	{	  while (*str && *str != ' ')	    {	      if (*str == 'C')		clval |= RB_CDROM;	      if (*str == 'a')		clval |= RB_ASKNAME;	      if (*str == 'b')		clval |= RB_HALT;	      if (*str == 'c')		clval |= RB_CONFIG;	      if (*str == 'd')		clval |= RB_KDB;	      if (*str == 'D')		clval |= RB_MULTIPLE;	      if (*str == 'g')		clval |= RB_GDB;	      if (*str == 'h')		clval |= RB_SERIAL;	      if (*str == 'm')		clval |= RB_MUTE;	      if (*str == 'r')		clval |= RB_DFLTROOT;	      if (*str == 's')		clval |= RB_SINGLE;	      if (*str == 'v')		clval |= RB_VERBOSE;	      str++;	    }	  continue;	}      str++;    }  if (type == KERNEL_TYPE_FREEBSD)    {      clval |= RB_BOOTINFO;      bi.bi_version = BOOTINFO_VERSION;      *arg = 0;      while ((--arg) > (char *) MB_CMDLINE_BUF && *arg != '/');      if (*arg == '/')	bi.bi_kernelname = arg + 1;      else	bi.bi_kernelname = 0;      bi.bi_nfs_diskless = 0;      bi.bi_n_bios_used = 0;	/* this field is apparently unused */      for (i = 0; i < N_BIOS_GEOM; i++)	{	  struct geometry geom;	  /* XXX Should check the return value.  */	  get_diskinfo (i + 0x80, &geom);	  /* FIXME: If HEADS or SECTORS is greater than 255, then this will	     break the geometry information. That is a drawback of BSD	     but not of GRUB.  */	  bi.bi_bios_geom[i] = (((geom.cylinders - 1) << 16)				+ (((geom.heads - 1) & 0xff) << 8)				+ (geom.sectors & 0xff));	}      bi.bi_size = sizeof (struct bootinfo);      bi.bi_memsizes_valid = 1;      bi.bi_bios_dev = saved_drive;      bi.bi_basemem = mbi.mem_lower;      bi.bi_extmem = extended_memory;      if (mbi.flags & MB_INFO_AOUT_SYMS)	{	  bi.bi_symtab = mbi.syms.a.addr;	  bi.bi_esymtab = mbi.syms.a.addr + 4	    + mbi.syms.a.tabsize + mbi.syms.a.strsize;	}#if 0      else if (mbi.flags & MB_INFO_ELF_SHDR)	{	  /* FIXME: Should check if a symbol table exists and, if exists,	     pass the table to BI.  */	}#endif      else	{	  bi.bi_symtab = 0;	  bi.bi_esymtab = 0;	}      /* call entry point */      (*entry_addr) (clval, bootdev, 0, 0, 0, ((int) (&bi)));    }  else    {      /*       *  We now pass the various bootstrap parameters to the loaded       *  image via the argument list.       *       *  This is the official list:       *       *  arg0 = 8 (magic)       *  arg1 = boot flags       *  arg2 = boot device       *  arg3 = start of symbol table (0 if not loaded)       *  arg4 = end of symbol table (0 if not loaded)       *  arg5 = transfer address from image       *  arg6 = transfer address for next image pointer       *  arg7 = conventional memory size (640)       *  arg8 = extended memory size (8196)       *       *  ...in actuality, we just pass the parameters used by the kernel.       */      /* call entry point */      unsigned long end_mark;      if (mbi.flags & MB_INFO_AOUT_SYMS)	end_mark = (mbi.syms.a.addr + 4		    + mbi.syms.a.tabsize + mbi.syms.a.strsize);      else	/* FIXME: it should be mbi.syms.e.size.  */	end_mark = 0;            (*entry_addr) (clval, bootdev, 0, end_mark,		     extended_memory, mbi.mem_lower);    }}

⌨️ 快捷键说明

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