📄 builtins.c
字号:
color_func (char *arg, int flags){ char *normal; char *highlight; int new_normal_color; int new_highlight_color; static char *color_list[16] = { "black", "blue", "green", "cyan", "red", "magenta", "brown", "light-gray", "dark-gray", "light-blue", "light-green", "light-cyan", "light-red", "light-magenta", "yellow", "white" }; /* Convert the color name STR into the magical number. */ static int color_number (char *str) { char *ptr; int i; int color = 0; /* Find the separator. */ for (ptr = str; *ptr && *ptr != '/'; ptr++) ; /* If not found, return -1. */ if (! *ptr) return -1; /* Terminate the string STR. */ *ptr++ = 0; /* If STR contains the prefix "blink-", then set the `blink' bit in COLOR. */ if (substring ("blink-", str) <= 0) { color = 0x80; str += 6; } /* Search for the color name. */ for (i = 0; i < 16; i++) if (grub_strcmp (color_list[i], str) == 0) { color |= i; break; } if (i == 16) return -1; str = ptr; nul_terminate (str); /* Search for the color name. */ for (i = 0; i < 8; i++) if (grub_strcmp (color_list[i], str) == 0) { color |= i << 4; break; } if (i == 8) return -1; return color; } normal = arg; highlight = skip_to (0, arg); new_normal_color = color_number (normal); if (new_normal_color < 0 && ! safe_parse_maxint (&normal, &new_normal_color)) return 1; /* The second argument is optional, so set highlight_color to inverted NORMAL_COLOR. */ if (! *highlight) new_highlight_color = ((new_normal_color >> 4) | ((new_normal_color & 0xf) << 4)); else { new_highlight_color = color_number (highlight); if (new_highlight_color < 0 && ! safe_parse_maxint (&highlight, &new_highlight_color)) return 1; } if (current_term->setcolor) current_term->setcolor (new_normal_color, new_highlight_color); return 0;}static struct builtin builtin_color ={ "color", color_func, BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, "color NORMAL [HIGHLIGHT]", "Change the menu colors. The color NORMAL is used for most" " lines in the menu, and the color HIGHLIGHT is used to highlight the" " line where the cursor points. If you omit HIGHLIGHT, then the" " inverted color of NORMAL is used for the highlighted line." " The format of a color is \"FG/BG\". FG and BG are symbolic color names." " A symbolic color name must be one of these: black, blue, green," " cyan, red, magenta, brown, light-gray, dark-gray, light-blue," " light-green, light-cyan, light-red, light-magenta, yellow and white." " But only the first eight names can be used for BG. You can prefix" " \"blink-\" to FG if you want a blinking foreground color."};/* configfile */static intconfigfile_func (char *arg, int flags){ char *new_config = config_file; /* Check if the file ARG is present. */ if (! grub_open (arg)) return 1; grub_close (); /* Copy ARG to CONFIG_FILE. */ while ((*new_config++ = *arg++) != 0) ;#ifdef GRUB_UTIL /* Force to load the configuration file. */ use_config_file = 1;#endif /* Make sure that the user will not be authoritative. */ auth = 0; /* Restart cmain. */ grub_longjmp (restart_env, 0); /* Never reach here. */ return 0;}static struct builtin builtin_configfile ={ "configfile", configfile_func, BUILTIN_CMDLINE | BUILTIN_HELP_LIST, "configfile FILE", "Load FILE as the configuration file."};/* debug */static intdebug_func (char *arg, int flags){ if (debug) { debug = 0; grub_printf (" Debug mode is turned off\n"); } else { debug = 1; grub_printf (" Debug mode is turned on\n"); } return 0;}static struct builtin builtin_debug ={ "debug", debug_func, BUILTIN_CMDLINE, "debug", "Turn on/off the debug mode."};/* default */static intdefault_func (char *arg, int flags){#ifndef SUPPORT_DISKLESS if (grub_strcmp (arg, "saved") == 0) { default_entry = saved_entryno; return 0; }#endif /* SUPPORT_DISKLESS */ if (! safe_parse_maxint (&arg, &default_entry)) return 1; return 0;}static struct builtin builtin_default ={ "default", default_func, BUILTIN_MENU,#if 0 "default [NUM | `saved']", "Set the default entry to entry number NUM (if not specified, it is" " 0, the first entry) or the entry number saved by savedefault."#endif};#ifdef GRUB_UTIL/* device */static intdevice_func (char *arg, int flags){ char *drive = arg; char *device; /* Get the drive number from DRIVE. */ if (! set_device (drive)) return 1; /* Get the device argument. */ device = skip_to (0, drive); /* Terminate DEVICE. */ nul_terminate (device); if (! *device || ! check_device (device)) { errnum = ERR_FILE_NOT_FOUND; return 1; } assign_device_name (current_drive, device); return 0;}static struct builtin builtin_device ={ "device", device_func, BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST, "device DRIVE DEVICE", "Specify DEVICE as the actual drive for a BIOS drive DRIVE. This command" " can be used only in the grub shell."};#endif /* GRUB_UTIL */#ifdef SUPPORT_NETBOOT/* dhcp */static intdhcp_func (char *arg, int flags){ /* For now, this is an alias for bootp. */ return bootp_func (arg, flags);}static struct builtin builtin_dhcp ={ "dhcp", dhcp_func, BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, "dhcp", "Initialize a network device via DHCP."};#endif /* SUPPORT_NETBOOT *//* displayapm */static intdisplayapm_func (char *arg, int flags){ if (mbi.flags & MB_INFO_APM_TABLE) { grub_printf ("APM BIOS information:\n" " Version: 0x%x\n" " 32-bit CS: 0x%x\n" " Offset: 0x%x\n" " 16-bit CS: 0x%x\n" " 16-bit DS: 0x%x\n" " 32-bit CS length: 0x%x\n" " 16-bit CS length: 0x%x\n" " 16-bit DS length: 0x%x\n", (unsigned) apm_bios_info.version, (unsigned) apm_bios_info.cseg, apm_bios_info.offset, (unsigned) apm_bios_info.cseg_16, (unsigned) apm_bios_info.dseg_16, (unsigned) apm_bios_info.cseg_len, (unsigned) apm_bios_info.cseg_16_len, (unsigned) apm_bios_info.dseg_16_len); } else { grub_printf ("No APM BIOS found or probe failed\n"); } return 0;}static struct builtin builtin_displayapm ={ "displayapm", displayapm_func, BUILTIN_CMDLINE | BUILTIN_HELP_LIST, "displayapm", "Display APM BIOS information."};/* displaymem */static intdisplaymem_func (char *arg, int flags){ if (get_eisamemsize () != -1) grub_printf (" EISA Memory BIOS Interface is present\n"); if (get_mmap_entry ((void *) SCRATCHADDR, 0) != 0 || *((int *) SCRATCHADDR) != 0) grub_printf (" Address Map BIOS Interface is present\n"); grub_printf (" Lower memory: %uK, " "Upper memory (to first chipset hole): %uK\n", mbi.mem_lower, mbi.mem_upper); if (mbi.flags & MB_INFO_MEM_MAP) { struct AddrRangeDesc *map = (struct AddrRangeDesc *) mbi.mmap_addr; int end_addr = mbi.mmap_addr + mbi.mmap_length; grub_printf (" [Address Range Descriptor entries " "immediately follow (values are 64-bit)]\n"); while (end_addr > (int) map) { char *str; if (map->Type == MB_ARD_MEMORY) str = "Usable RAM"; else str = "Reserved"; grub_printf (" %s: Base Address: 0x%x X 4GB + 0x%x,\n" " Length: 0x%x X 4GB + 0x%x bytes\n", str, (unsigned long) (map->BaseAddr >> 32), (unsigned long) (map->BaseAddr & 0xFFFFFFFF), (unsigned long) (map->Length >> 32), (unsigned long) (map->Length & 0xFFFFFFFF)); map = ((struct AddrRangeDesc *) (((int) map) + 4 + map->size)); } } return 0;}static struct builtin builtin_displaymem ={ "displaymem", displaymem_func, BUILTIN_CMDLINE | BUILTIN_HELP_LIST, "displaymem", "Display what GRUB thinks the system address space map of the" " machine is, including all regions of physical RAM installed."};/* dump FROM TO */#ifdef GRUB_UTILstatic intdump_func (char *arg, int flags){ char *from, *to; FILE *fp; char c; from = arg; to = skip_to (0, arg); if (! *from || ! *to) { errnum = ERR_BAD_ARGUMENT; return 1; } nul_terminate (from); nul_terminate (to); if (! grub_open (from)) return 1; fp = fopen (to, "w"); if (! fp) { errnum = ERR_WRITE; return 1; } while (grub_read (&c, 1)) if (fputc (c, fp) == EOF) { errnum = ERR_WRITE; fclose (fp); return 1; } if (fclose (fp) == EOF) { errnum = ERR_WRITE; return 1; } grub_close (); return 0;}static struct builtin builtin_dump = { "dump", dump_func, BUILTIN_CMDLINE, "dump FROM TO", "Dump the contents of the file FROM to the file TO. FROM must be" " a GRUB file and TO must be an OS file." };#endif /* GRUB_UTIL */static char embed_info[32];/* embed *//* Embed a Stage 1.5 in the first cylinder after MBR or in the bootloader block in a FFS. */static intembed_func (char *arg, int flags){ char *stage1_5; char *device; char *stage1_5_buffer = (char *) RAW_ADDR (0x100000); int len, size; int sector; stage1_5 = arg; device = skip_to (0, stage1_5); /* Open a Stage 1.5. */ if (! grub_open (stage1_5)) return 1; /* Read the whole of the Stage 1.5. */ len = grub_read (stage1_5_buffer, -1); grub_close (); if (errnum) return 1; size = (len + SECTOR_SIZE - 1) / SECTOR_SIZE; /* Get the device where the Stage 1.5 will be embedded. */ set_device (device); if (errnum) return 1; if (current_partition == 0xFFFFFF) { /* Embed it after the MBR. */ char mbr[SECTOR_SIZE]; char ezbios_check[2*SECTOR_SIZE]; int i; /* Open the partition. */ if (! open_partition ()) return 1; /* No floppy has MBR. */ if (! (current_drive & 0x80)) { errnum = ERR_DEV_VALUES; return 1; } /* Read the MBR of CURRENT_DRIVE. */ if (! rawread (current_drive, PC_MBR_SECTOR, 0, SECTOR_SIZE, mbr)) return 1; /* Sanity check. */ if (! PC_MBR_CHECK_SIG (mbr)) { errnum = ERR_BAD_PART_TABLE; return 1; } /* Check if the disk can store the Stage 1.5. */ for (i = 0; i < 4; i++) if (PC_SLICE_TYPE (mbr, i) && PC_SLICE_START (mbr, i) - 1 < size) { errnum = ERR_NO_DISK_SPACE; return 1; } /* Check for EZ-BIOS signature. It should be in the third * sector, but due to remapping it can appear in the second, so * load and check both. */ if (! rawread (current_drive, 1, 0, 2 * SECTOR_SIZE, ezbios_check)) return 1; if (! memcmp (ezbios_check + 3, "AERMH", 5) || ! memcmp (ezbios_check + 512 + 3, "AERMH", 5)) { /* The space after the MBR is used by EZ-BIOS which we must * not overwrite. */ errnum = ERR_NO_DISK_SPACE; return 1; } sector = 1; } else { /* Embed it in the bootloader block in the filesystem. */ int start_sector; /* Open the partition. */ if (! open_device ()) return 1; /* Check if the current slice supports embedding. */ if (fsys_table[fsys_type].embed_func == 0 || ! fsys_table[fsys_type].embed_func (&start_sector, size)) { errnum = ERR_DEV_VALUES; return 1; } sector = part_start + start_sector; } /* Clear the cache. */ buf_track = -1; /* Now perform the embedding. */ if (! devwrite (sector - part_start, size, stage1_5_buffer)) return 1; grub_printf (" %d sectors are embedded.\n", size); grub_sprintf (embed_info, "%d+%d", sector - part_start, size);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -