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

📄 builtins.c

📁 i386的bootloader源码grub
💻 C
📖 第 1 页 / 共 5 页
字号:
  errnum = ERR_UNRECOGNIZED;  return 1;  #else /* ! GRUB_UTIL */    unsigned short *port;    /* Get the drive number.  */  set_device (arg);  if (errnum)    return 1;  /* Clean out IO_MAP.  */  grub_memset ((char *) io_map, 0, IO_MAP_SIZE * sizeof (unsigned short));  /* Track the int13 handler.  */  track_int13 (current_drive);    /* Print out the result.  */  for (port = io_map; *port != 0; port++)    grub_printf (" 0x%x", (unsigned int) *port);  return 0;  #endif /* ! GRUB_UTIL */}static struct builtin builtin_ioprobe ={  "ioprobe",  ioprobe_func,  BUILTIN_CMDLINE,  "ioprobe DRIVE",  "Probe I/O ports used for the drive DRIVE."};/* kernel */static intkernel_func (char *arg, int flags){  int len;  kernel_t suggested_type = KERNEL_TYPE_NONE;  unsigned long load_flags = 0;#ifndef AUTO_LINUX_MEM_OPT  load_flags |= KERNEL_LOAD_NO_MEM_OPTION;#endif  /* Deal with GNU-style long options.  */  while (1)    {      /* If the option `--type=TYPE' is specified, convert the string to	 a kernel type.  */      if (grub_memcmp (arg, "--type=", 7) == 0)	{	  arg += 7;	  	  if (grub_memcmp (arg, "netbsd", 6) == 0)	    suggested_type = KERNEL_TYPE_NETBSD;	  else if (grub_memcmp (arg, "freebsd", 7) == 0)	    suggested_type = KERNEL_TYPE_FREEBSD;	  else if (grub_memcmp (arg, "openbsd", 7) == 0)	    /* XXX: For now, OpenBSD is identical to NetBSD, from GRUB's	       point of view.  */	    suggested_type = KERNEL_TYPE_NETBSD;	  else if (grub_memcmp (arg, "linux", 5) == 0)	    suggested_type = KERNEL_TYPE_LINUX;	  else if (grub_memcmp (arg, "biglinux", 8) == 0)	    suggested_type = KERNEL_TYPE_BIG_LINUX;	  else if (grub_memcmp (arg, "multiboot", 9) == 0)	    suggested_type = KERNEL_TYPE_MULTIBOOT;	  else	    {	      errnum = ERR_BAD_ARGUMENT;	      return 1;	    }	}      /* If the `--no-mem-option' is specified, don't pass a Linux's mem	 option automatically. If the kernel is another type, this flag	 has no effect.  */      else if (grub_memcmp (arg, "--no-mem-option", 15) == 0)	load_flags |= KERNEL_LOAD_NO_MEM_OPTION;      else	break;      /* Try the next.  */      arg = skip_to (0, arg);    }        len = grub_strlen (arg);  /* Reset MB_CMDLINE.  */  mb_cmdline = (char *) MB_CMDLINE_BUF;  if (len + 1 > MB_CMDLINE_BUFLEN)    {      errnum = ERR_WONT_FIT;      return 1;    }  /* Copy the command-line to MB_CMDLINE.  */  grub_memmove (mb_cmdline, arg, len + 1);  kernel_type = load_image (arg, mb_cmdline, suggested_type, load_flags);  if (kernel_type == KERNEL_TYPE_NONE)    return 1;  mb_cmdline += len + 1;  return 0;}static struct builtin builtin_kernel ={  "kernel",  kernel_func,  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,  "kernel [--no-mem-option] [--type=TYPE] FILE [ARG ...]",  "Attempt to load the primary boot image from FILE. The rest of the"  " line is passed verbatim as the \"kernel command line\".  Any modules"  " must be reloaded after using this command. The option --type is used"  " to suggest what type of kernel to be loaded. TYPE must be either of"  " \"netbsd\", \"freebsd\", \"openbsd\", \"linux\", \"biglinux\" and"  " \"multiboot\". The option --no-mem-option tells GRUB not to pass a"  " Linux's mem option automatically."};/* lock */static intlock_func (char *arg, int flags){  if (! auth && password)    {      errnum = ERR_PRIVILEGED;      return 1;    }  return 0;}static struct builtin builtin_lock ={  "lock",  lock_func,  BUILTIN_CMDLINE,  "lock",  "Break a command execution unless the user is authenticated."};  /* makeactive */static intmakeactive_func (char *arg, int flags){  if (! make_saved_active ())    return 1;  return 0;}static struct builtin builtin_makeactive ={  "makeactive",  makeactive_func,  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,  "makeactive",  "Set the active partition on the root disk to GRUB's root device."  " This command is limited to _primary_ PC partitions on a hard disk."};/* map *//* Map FROM_DRIVE to TO_DRIVE.  */static intmap_func (char *arg, int flags){  char *to_drive;  char *from_drive;  unsigned long to, from;  int i;    to_drive = arg;  from_drive = skip_to (0, arg);  /* Get the drive number for TO_DRIVE.  */  set_device (to_drive);  if (errnum)    return 1;  to = current_drive;  /* Get the drive number for FROM_DRIVE.  */  set_device (from_drive);  if (errnum)    return 1;  from = current_drive;  /* Search for an empty slot in BIOS_DRIVE_MAP.  */  for (i = 0; i < DRIVE_MAP_SIZE; i++)    {      /* Perhaps the user wants to override the map.  */      if ((bios_drive_map[i] & 0xff) == from)	break;            if (! bios_drive_map[i])	break;    }  if (i == DRIVE_MAP_SIZE)    {      errnum = ERR_WONT_FIT;      return 1;    }  if (to == from)    /* If TO is equal to FROM, delete the entry.  */    grub_memmove ((char *) &bios_drive_map[i], (char *) &bios_drive_map[i + 1],		  sizeof (unsigned short) * (DRIVE_MAP_SIZE - i));  else    bios_drive_map[i] = from | (to << 8);    return 0;}static struct builtin builtin_map ={  "map",  map_func,  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,  "map TO_DRIVE FROM_DRIVE",  "Map the drive FROM_DRIVE to the drive TO_DRIVE. This is necessary"  " when you chain-load some operating systems, such as DOS, if such an"  " OS resides at a non-first drive."};#ifdef USE_MD5_PASSWORDS/* md5crypt */static intmd5crypt_func (char *arg, int flags){  char crypted[36];  char key[32];  unsigned int seed;  int i;  const char *const seedchars =    "./0123456789ABCDEFGHIJKLMNOPQRST"    "UVWXYZabcdefghijklmnopqrstuvwxyz";    /* First create a salt.  */  /* The magical prefix.  */  grub_memset (crypted, 0, sizeof (crypted));  grub_memmove (crypted, "$1$", 3);  /* Create the length of a salt.  */  seed = currticks ();  /* Generate a salt.  */  for (i = 0; i < 8 && seed; i++)    {      /* FIXME: This should be more random.  */      crypted[3 + i] = seedchars[seed & 0x3f];      seed >>= 6;    }  /* A salt must be terminated with `$', if it is less than 8 chars.  */  crypted[3 + i] = '$';#ifdef DEBUG_MD5CRYPT  grub_printf ("salt = %s\n", crypted);#endif    /* Get a password.  */  grub_memset (key, 0, sizeof (key));  get_cmdline ("Password: ", key, sizeof (key) - 1, '*', 0);  /* Crypt the key.  */  make_md5_password (key, crypted);  grub_printf ("Encrypted: %s\n", crypted);  return 0;}static struct builtin builtin_md5crypt ={  "md5crypt",  md5crypt_func,  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,  "md5crypt",  "Generate a password in MD5 format."};#endif /* USE_MD5_PASSWORDS *//* module */static intmodule_func (char *arg, int flags){  int len = grub_strlen (arg);  switch (kernel_type)    {    case KERNEL_TYPE_MULTIBOOT:      if (mb_cmdline + len + 1 > (char *) MB_CMDLINE_BUF + MB_CMDLINE_BUFLEN)	{	  errnum = ERR_WONT_FIT;	  return 1;	}      grub_memmove (mb_cmdline, arg, len + 1);      if (! load_module (arg, mb_cmdline))	return 1;      mb_cmdline += len + 1;      break;    case KERNEL_TYPE_LINUX:    case KERNEL_TYPE_BIG_LINUX:      if (! load_initrd (arg))	return 1;      break;    default:      errnum = ERR_NEED_MB_KERNEL;      return 1;    }  return 0;}static struct builtin builtin_module ={  "module",  module_func,  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,  "module FILE [ARG ...]",  "Load a boot module FILE for a Multiboot format boot image (no"  " interpretation of the file contents is made, so users of this"  " command must know what the kernel in question expects). The"  " rest of the line is passed as the \"module command line\", like"  " the `kernel' command."};/* modulenounzip */static intmodulenounzip_func (char *arg, int flags){  int ret;#ifndef NO_DECOMPRESSION  no_decompression = 1;#endif  ret = module_func (arg, flags);#ifndef NO_DECOMPRESSION  no_decompression = 0;#endif  return ret;}static struct builtin builtin_modulenounzip ={  "modulenounzip",  modulenounzip_func,  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,  "modulenounzip FILE [ARG ...]",  "The same as `module', except that automatic decompression is"  " disabled."};/* pager [on|off] */static intpager_func (char *arg, int flags){  /* If ARG is empty, toggle the flag.  */  if (! *arg)    use_pager = ! use_pager;  else if (grub_memcmp (arg, "on", 2) == 0)    use_pager = 1;  else if (grub_memcmp (arg, "off", 3) == 0)    use_pager = 0;  else    {      errnum = ERR_BAD_ARGUMENT;      return 1;    }  grub_printf (" Internal pager is now %s\n", use_pager ? "on" : "off");  return 0;}static struct builtin builtin_pager ={  "pager",  pager_func,  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,  "pager [FLAG]",  "Toggle pager mode with no argument. If FLAG is given and its value"  " is `on', turn on the mode. If FLAG is `off', turn off the mode."};/* partnew PART TYPE START LEN */static intpartnew_func (char *arg, int flags){  int new_type, new_start, new_len;  int start_cl, start_ch, start_dh;  int end_cl, end_ch, end_dh;  int entry;  char mbr[512];  /* Convert a LBA address to a CHS address in the INT 13 format.  */  auto void lba_to_chs (int lba, int *cl, int *ch, int *dh);  void lba_to_chs (int lba, int *cl, int *ch, int *dh)    {      int cylinder, head, sector;      sector = lba % buf_geom.sectors + 1;      head = (lba / buf_geom.sectors) % buf_geom.heads;      cylinder = lba / (buf_geom.sectors * buf_geom.heads);      if (cylinder >= buf_geom.cylinders)	cylinder = buf_geom.cylinders - 1;            *cl = sector | ((cylinder & 0x300) >> 2);      *ch = cylinder & 0xFF;      *dh = head;    }        /* Get the drive and the partition.  */  if (! set_device (arg))    return 1;  /* The drive must be a hard disk.  */  if (! (current_drive & 0x80))    {      errnum = ERR_BAD_ARGUMENT;      return 1;    }  /* The partition must a primary partition.  */  if ((current_partition >> 16) > 3      || (current_partition & 0xFFFF) != 0xFFFF)    {      errnum = ERR_BAD_ARGUMENT;      return 1;    }  entry = current_partition >> 16;    /* Get the new partition type.  */  arg = skip_to (0, arg);  if (! safe_parse_maxint (&arg, &new_type))    return 1;  /* The partition type is unsigned char.  */  if (new_type > 0xFF)    {      errnum = ERR_BAD_ARGUMENT;      return 1;    }  /* Get the new partition start.  */  arg = skip_to (0, arg);  if (! safe_parse_maxint (&arg, &new_start))    return 1;    /* Get the new partition length.  */  arg = skip_to (0, arg);  if (! safe_parse_maxint (&arg, &new_len))    return 1;  /* Read the MBR.  */  if (! rawread (current_drive, 0, 0, SECTOR_SIZE, mbr))    return 1;  /* Check if the new partition will fit in the disk.  */  if (new_start + new_len > buf_geom.total_sectors)    {      errnum = ERR_GEOM;      return 1;    }  /* Store the partition information in the MBR.  */  lba_to_chs (new_start, &start_cl, &start_ch, &start_dh);  lba_to_chs (new_start + new_len - 1, &end_cl, &end_ch, &end_dh);  PC_SLICE_FLAG (mbr, entry) = 0;  PC_SLICE_HEAD (mbr, entry) = start_dh;  PC_SLICE_SEC (mbr, entry) = start_cl;  PC_SLICE_CYL (mbr, entry) = start_ch;  PC_SLICE_TYPE (mbr, entry) = new_type;  PC_SLICE_EHEAD (mbr, entry) = end_dh;  PC_SLICE_ESEC (mbr, entry) = end_cl;  PC_SLICE_ECYL (mbr, entry) = end_ch;  PC_SLICE_START (mbr, entry) = new_start;  PC_SLICE_LENGTH (mbr, entry) = new_len;  /* Make sure that the MBR has a valid signature.  */  PC_MBR_SIG (mbr) = PC_MBR_SIGNATURE;    /* Write back the MBR to the disk.  */  buf_track = -1;  if (! rawwrite (current_drive, 0, mbr))    return 1;  return 0;}static struct builtin builtin_partnew ={  "partnew",  partnew_func,  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,  "partnew PART TYPE START LEN",  "Create a primary partition at the starting address START with the"  " length LEN, with the type TYPE. START and LEN are in sector units."};/* parttype PART TYPE */static intparttype_func (char *arg, int flags){  int new_type;  unsigned long part = 0xFFFFFF;  unsigned long start, len, offset, ext_offset;  int entry, type;  char mbr[512];  /* Get the drive and the partition.  */  if (! set_device (arg))    return 1;  /* The drive must be a hard disk.  */  if (! (current_drive & 0x80))    {      errnum = ERR_BAD_ARGUMENT;      return 1;    }    /* The partition must be a PC slice.  */  if ((current_partition >> 16) == 0xFF      || (current_partition & 0xFFFF) != 0xFFFF)    {      errnum = ERR_BAD_ARGUMENT;      return 1;    }  /* Get the new partition type.  */  arg = skip_to (0, arg);  if (! safe_parse_maxint (&arg, &new_type))    return 1;  /* The partition type is unsigned char.  */  if (new_type > 0xFF) 

⌨️ 快捷键说明

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