📄 builtins.c
字号:
/* builtins.c - the GRUB builtin commands *//* * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* Include stdio.h before shared.h, because we can't define WITHOUT_LIBC_STUBS here. */#ifdef GRUB_UTIL# include <stdio.h>#endif#include <shared.h>#include <filesys.h>#include <term.h>#ifdef SUPPORT_NETBOOT# define GRUB 1# include <etherboot.h>#endif#ifdef SUPPORT_SERIAL# include <serial.h># include <terminfo.h>#endif#ifdef GRUB_UTIL# include <device.h>#else /* ! GRUB_UTIL */# include <apic.h>//# include <smp-imps.h>#endif /* ! GRUB_UTIL */#ifdef USE_MD5_PASSWORDS# include <md5.h>#endif#include "freebsd.h"/* The type of kernel loaded. */kernel_t kernel_type;static kernel_t kernel_type_orig;/* The boot device. */static int bootdev;#if 0/* True when the debug mode is turned on, and false when it is turned off. */int debug = 0;#else/* 0 for silent, 1 for normal, 2..MAX_UINT for verbose. * if debug == MAX_UINT or debug < 0, then filesystem debug mode is on. * (MAX_UINT is 0x7FFFFFFF) */int debug = 1;#endif/* The default entry. */int default_entry = 0;/* The fallback entry. */int fallback_entryno;int fallback_entries[MAX_FALLBACK_ENTRIES];/* The number of current entry. */int current_entryno;/* The address for Multiboot command-line buffer. */static char *mb_cmdline;static char kernel_option_video[64];/* The password. */char *password;/* The password type. */password_t password_type;/* The flag for indicating that the user is authoritative. */int auth = 0;/* The timeout. */int grub_timeout = -1;/* Whether to show the menu or not. */int show_menu = 1;int use_config_file = 1;extern unsigned long i;//extern char *mbr;#if !defined(STAGE1_5) && !defined(GRUB_UTIL)/* The first sector of stage2 can be reused as a tmp buffer. * Do NOT write more than 512 bytes to this buffer! * The stage2-body, i.e., the pre_stage2, starts at 0x8200! * Do NOT overwrite the pre_stage2 code at 0x8200! */extern char *mbr /* = (char *)0x8000 */; /* 512-byte buffer for any use. */#elseextern char mbr[SECTOR_SIZE];#endif /* STAGE1_5 || GRUB_UTIL */#ifndef STAGE1_5extern int dir (char *dirname);#endif /* STAGE1_5 */#ifdef SUPPORT_GRAPHICSextern int outline;#endif /* SUPPORT_GRAPHICS */#ifndef GRUB_UTIL/* Whether the drive map hook is on. *///static int int13_on_hook = 0;//static int floppy_not_inserted[4] = {0, 0, 0, 0};/* The BIOS drive map. */extern struct drive_map_slot bios_drive_map[DRIVE_MAP_SIZE + 1];extern struct drive_map_slot hooked_drive_map[DRIVE_MAP_SIZE + 1];/* backup of original BIOS floppy-count byte in 0x410 */extern char floppies_orig;/* backup of original BIOS harddrive-count byte in 0x475 */extern char harddrives_orig;extern unsigned short chain_load_segment;//0x0000;extern unsigned short chain_load_offset;//0x7c00;extern unsigned int chain_load_length;//0x200;extern unsigned short chain_boot_CS;//0x0000;extern unsigned short chain_boot_IP;//0x7c00;extern unsigned long chain_ebx;extern unsigned long chain_ebx_set;extern unsigned long chain_edx;extern unsigned long chain_edx_set;extern unsigned long chain_enable_gateA20;extern char HMA_start[];#endif /* ! GRUB_UTIL */static int chainloader_load_segment = 0;static int chainloader_load_segment_orig = 0;static int chainloader_load_offset = 0;static int chainloader_load_offset_orig = 0;static int chainloader_load_length = 0;static int chainloader_load_length_orig = 0;static int chainloader_skip_length = 0;static int chainloader_skip_length_orig = 0;static int chainloader_boot_CS = 0;static int chainloader_boot_CS_orig = 0;static int chainloader_boot_IP = 0;static int chainloader_boot_IP_orig = 0;static long chainloader_ebx = 0;static long chainloader_ebx_orig = 0;static int chainloader_ebx_set = 0;static int chainloader_ebx_set_orig = 0;static long chainloader_edx = 0;static long chainloader_edx_orig = 0;static int chainloader_edx_set = 0;static int chainloader_edx_set_orig = 0;static int chainloader_disable_A20 = 0;static int chainloader_disable_A20_orig = 0;static int is_sdi = 0;static int is_sdi_orig = 0;static int is_raw = 0;static int is_raw_orig = 0;static int is_isolinux = 0;static int is_isolinux_orig = 0;static char chainloader_file[256];static char chainloader_file_orig[256];static const char *warning_defaultfile = "# WARNING: If you want to edit this file directly, do not remove any line";#ifndef GRUB_UTILstatic intdrive_map_slot_empty (struct drive_map_slot item){ unsigned long *array = (unsigned long *)&item; unsigned long n = sizeof (struct drive_map_slot) / sizeof (unsigned long); while (n) { if (*array) return 0; array++; n--; } return 1; //if (*(unsigned long *)(&(item.from_drive))) return 0; //if (item.start_sector) return 0; //if (item.sector_count) return 0; //return 1;}static intdrive_map_slot_equal (struct drive_map_slot a, struct drive_map_slot b){ //return ! grub_memcmp ((void *)&(a.from_drive), (void *)&(b.from_drive), sizeof(struct drive_map_slot)); return ! grub_memcmp ((void *)&a, (void *)&b, sizeof(struct drive_map_slot)); //if (*(unsigned long *)(&(a.from_drive)) != *(unsigned long *)(&(b.from_drive))) return 0; //if (a.start_sector != b.start_sector) return 0; //if (a.sector_count != b.sector_count) return 0; //return 1;}static int map_func (char *arg, int flags);static int disable_map_info = 0;#endif /* ! GRUB_UTIL *//* Prototypes for allowing straightfoward calling of builtins functions inside other functions. */static int configfile_func (char *arg, int flags);//static char *set_device (char *device);//static int real_open_partition (int flags);//static int open_partition (void);int commandline_func (char *arg, int flags);int errnum_func (char *arg, int flags);/* Initialize the data for builtins. */voidinit_builtins (void){ kernel_type = KERNEL_TYPE_NONE; /* BSD and chainloading evil hacks! */ bootdev = set_bootdev (0); mb_cmdline = (char *) MB_CMDLINE_BUF; *kernel_option_video = 0; /* initialize the string to be empty. */}/* Initialize the data for the configuration file. */voidinit_config (void){ default_entry = 0; password = 0; fallback_entryno = -1; fallback_entries[0] = -1; grub_timeout = -1;}/* Check a password for correctness. Returns 0 if password was correct, and a value != 0 for error, similarly to strcmp. */intcheck_password (char *entered, char* expected, password_t type){ switch (type) { case PASSWORD_PLAIN: return strcmp (entered, expected);#ifdef USE_MD5_PASSWORDS case PASSWORD_MD5: return check_md5_password (entered, expected);#endif default: /* unsupported password type: be secure */ return 1; }}/* Print which sector is read when loading a file. */static voiddisk_read_print_func (unsigned long sector, unsigned long offset, unsigned long length){ grub_printf ("[%d,%d,%d]", sector, offset, length);}extern int rawread_ignore_memmove_overflow; /* defined in disk_io.c */static long query_block_entries = 0;static unsigned long map_start_sector = 0;static unsigned long map_num_sectors = 0;static unsigned long blklst_start_sector;static unsigned long blklst_num_sectors;static unsigned long blklst_num_entries;static unsigned long blklst_last_length; static void disk_read_blocklist_func (unsigned long sector, unsigned long offset, unsigned long length); /* Collect contiguous blocks into one entry as many as possible, and print the blocklist notation on the screen. */static voiddisk_read_blocklist_func (unsigned long sector, unsigned long offset, unsigned long length){ if (blklst_num_sectors > 0) { if (blklst_start_sector + blklst_num_sectors == sector && offset == 0 && blklst_last_length == buf_geom.sector_size/*SECTOR_SIZE*/) { blklst_num_sectors++; blklst_last_length = length; return; } else { if (query_block_entries >= 0) { if (blklst_last_length == buf_geom.sector_size/*SECTOR_SIZE*/) grub_printf ("%s%d+%d", blklst_num_entries ? "," : "", blklst_start_sector - part_start, blklst_num_sectors); else if (blklst_num_sectors > 1) grub_printf ("%s%d+%d,%d[0-%d]", blklst_num_entries ? "," : "", blklst_start_sector - part_start, blklst_num_sectors-1, blklst_start_sector + blklst_num_sectors-1 - part_start, blklst_last_length); else grub_printf ("%s%d[0-%d]", blklst_num_entries ? "," : "", blklst_start_sector - part_start, blklst_last_length); } blklst_num_entries++; blklst_num_sectors = 0; } } if (offset > 0) { if (query_block_entries >= 0) grub_printf("%s%d[%d-%d]", blklst_num_entries ? "," : "", sector - part_start, offset, offset + length); blklst_num_entries++; } else { blklst_start_sector = sector; blklst_num_sectors = 1; blklst_last_length = length; }}/* blocklist */static intblocklist_func (char *arg, int flags){#ifdef GRUB_UTIL char *dummy = (char *) RAW_ADDR (0x100000);#else char *dummy = (char *) RAW_ADDR (0x400000);#endif int err; blklst_start_sector = 0; blklst_num_sectors = 0; blklst_num_entries = 0; blklst_last_length = 0; map_start_sector = 0; map_num_sectors = 0;//grub_printf ("before open()\n"); /* Open the file. */ if (! grub_open (arg)) goto fail_open;//grub_printf ("after open()\n");//grub_printf ("geometry->sector_size=%d\n", buf_geom.sector_size); /* Print the device name. */ if (query_block_entries >= 0) grub_printf ("(%cd%d", (current_drive & 0x80) ? 'h' : 'f', current_drive & ~0x80); if ((current_partition & 0xFF0000) != 0xFF0000) if (query_block_entries >= 0) grub_printf (",%d", (current_partition >> 16) & 0xFF); if ((current_partition & 0x00FF00) != 0x00FF00) if (query_block_entries >= 0) grub_printf (",%c", 'a' + ((current_partition >> 8) & 0xFF)); if (query_block_entries >= 0) grub_printf (")");//grub_printf ("before read()\n"); rawread_ignore_memmove_overflow = 1; /* Read in the whole file to DUMMY. */ disk_read_hook = disk_read_blocklist_func; err = grub_read (dummy, query_block_entries < 0 ? buf_geom.sector_size/*SECTOR_SIZE*/ : -1); disk_read_hook = 0; rawread_ignore_memmove_overflow = 0; if (! err) goto fail_read;//grub_printf ("after read()\n"); /* The last entry may not be printed yet. Don't check if it is a * full sector, since it doesn't matter if we read too much. */ if (blklst_num_sectors > 0) { if (query_block_entries >= 0) grub_printf ("%s%d+%d", blklst_num_entries ? "," : "", blklst_start_sector - part_start, blklst_num_sectors); blklst_num_entries++; } if (query_block_entries >= 0) grub_putchar ('\n');#if 0 if (num_entries > 1) query_block_entries = num_entries; else { query_block_entries = 1; map_start_sector = start_sector; map_num_sectors = num_sectors; }#endif if (query_block_entries < 0) {//grub_printf ("blklist1: start_sector=%d, num_sectors=%d, num_entries=%d, last_length=%d, filepos=%d, filemax=%d\n",start_sector, num_sectors, num_entries, last_length, filepos, filemax); map_start_sector = blklst_start_sector; blklst_start_sector = 0; blklst_num_sectors = 0; blklst_num_entries = 0; blklst_last_length = 0; rawread_ignore_memmove_overflow = 1; /* read in the last sector to DUMMY */ filepos = filemax ? (filemax - 1) & (-buf_geom.sector_size/*SECTOR_SIZE*/) : filemax; disk_read_hook = disk_read_blocklist_func; err = grub_read (dummy, -1); disk_read_hook = 0; rawread_ignore_memmove_overflow = 0;//grub_printf ("blklist2: start_sector=%d, num_sectors=%d, num_entries=%d, last_length=%d, filepos=%d, filemax=%d, map_num_sectors=%d, query_block_entries=%d\n",start_sector, num_sectors, num_entries, last_length, filepos, filemax, map_num_sectors, query_block_entries); if (! err) goto fail_read; map_num_sectors = blklst_start_sector - map_start_sector + 1; query_block_entries = filemax ? map_num_sectors - ((filemax - 1) / buf_geom.sector_size/*>> SECTOR_BITS*/) : 2; }fail_read: grub_close ();fail_open: if (query_block_entries < 0) query_block_entries = 0; return ! errnum;}static struct builtin builtin_blocklist ={ "blocklist", blocklist_func, BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST, "blocklist FILE", "Print the blocklist notation of the file FILE."};#if ! defined(GRUB_UTIL) && ! defined (STAGE1_5)/* WinME support by bean. Thanks! */// The following routines are used to decompress IO.SYS from WinMEstatic int ibuf_pos;static char *ibuf_ptr,*obuf_ptr;static unsigned short ibuf_tab[16];static void ibuf_init(char* buf);static unsigned short ibuf_read(int nbits);static int expand_block(int nsec);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -