📄 common.c
字号:
/* common.c - miscellaneous shared variables and routines *//* * GRUB -- GRand Unified Bootloader * Copyright (C) 1999,2000,2001,2002,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 <shared.h>#include <iso9660.h>#ifdef SUPPORT_DISKLESS# define GRUB 1# include <etherboot.h>#endif/* * Shared BIOS/boot data. */struct multiboot_info mbi;unsigned long saved_drive;unsigned long saved_partition;char saved_dir[256];//unsigned long cdrom_drives[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};unsigned long cdrom_drive = GRUB_INVALID_DRIVE;unsigned long force_cdrom_as_boot_device = 1;unsigned long ram_drive;unsigned long rd_base = 0; /* Note the rd_base value of -1 invalidates the ram drive. */unsigned long rd_size = 0; /* The rd_size 0 stands for 4GB, not for length of 0. */unsigned long saved_mem_upper;unsigned long saved_mem_lower;unsigned long saved_mmap_addr;unsigned long saved_mmap_length;#ifndef STAGE1_5/* This saves the maximum size of extended memory (in KB). */unsigned long extended_memory;unsigned long init_free_mem_start;#endifint is64bit = 0;int errorcheck = 1;/* * Error code stuff. */grub_error_t errnum = ERR_NONE;#ifndef STAGE1_5char *err_list[] ={ [ERR_NONE] = 0, [ERR_BAD_ARGUMENT] = "Invalid argument", [ERR_BAD_FILENAME] = "Filename must be either an absolute pathname or blocklist", [ERR_BAD_FILETYPE] = "Bad file or directory type", [ERR_BAD_GZIP_DATA] = "Bad or corrupt data while decompressing file", [ERR_BAD_GZIP_HEADER] = "Bad or incompatible header in compressed file", [ERR_BAD_PART_TABLE] = "Partition table invalid or corrupt", [ERR_BAD_VERSION] = "Mismatched or corrupt version of stage1/stage2", [ERR_BELOW_1MB] = "Loading below 1MB is not supported", [ERR_BOOT_COMMAND] = "Kernel must be loaded before booting", [ERR_BOOT_FAILURE] = "Unknown boot failure", [ERR_BOOT_FEATURES] = "Unsupported Multiboot features requested", [ERR_DEV_FORMAT] = "Unrecognized device string, or you omitted the required DEVICE part which should lead the filename.", [ERR_DEV_NEED_INIT] = "Device not initialized yet", [ERR_DEV_VALUES] = "Invalid device requested", [ERR_EXEC_FORMAT] = "Invalid or unsupported executable format", [ERR_FILELENGTH] = "Filesystem compatibility error, cannot read whole file", [ERR_FILENAME_FORMAT] = "The leading DEVICE of the filename to find must be stripped off,\n\tand DIR for set-root must begin in a slash(/).", [ERR_FILE_NOT_FOUND] = "File not found", [ERR_FSYS_CORRUPT] = "Inconsistent filesystem structure", [ERR_FSYS_MOUNT] = "Cannot mount selected partition", [ERR_GEOM] = "Selected cylinder exceeds maximum supported by BIOS", [ERR_HD_VOL_START_0] = "The BPB hidden_sectors should not be zero for a hard-disk partition boot sector", [ERR_IN_SITU_FLOPPY] = "Only hard drives could be mapped in situ.", [ERR_IN_SITU_MEM] = "Should not use --mem together with --in-situ.", [ERR_NEED_LX_KERNEL] = "Linux kernel must be loaded before initrd", [ERR_NEED_MB_KERNEL] = "Multiboot kernel must be loaded before modules", [ERR_NO_DISK] = "Selected disk does not exist", [ERR_NO_DISK_SPACE] = "No spare sectors on the disk", [ERR_NO_PART] = "No such partition", [ERR_NO_HEADS] = "The number of heads must be specified. The `--heads=0' option tells map to choose a value(but maybe unsuitable) for you", [ERR_NO_SECTORS] = "The number of sectors per track must be specified. The `--sectors-per-track=0' option tells map to choose a value(but maybe unsuitable) for you", [ERR_NON_CONTIGUOUS] = "File for drive emulation must be in one contiguous disk area", [ERR_NUMBER_OVERFLOW] = "Overflow while parsing number", [ERR_NUMBER_PARSING] = "Error while parsing number", [ERR_OUTSIDE_PART] = "Attempt to access block outside partition", [ERR_PRIVILEGED] = "Must be authenticated", [ERR_READ] = "Disk read error", [ERR_SYMLINK_LOOP] = "Too many symbolic links", [ERR_UNALIGNED] = "File is not sector aligned", [ERR_UNRECOGNIZED] = "Unrecognized command", [ERR_WONT_FIT] = "Selected item cannot fit into memory", [ERR_WRITE] = "Disk write error", [ERR_INT13_ON_HOOK] = "The int13 handler already on hook", [ERR_INT13_OFF_HOOK] = "The int13 handler not yet on hook", [ERR_NO_DRIVE_MAPPED] = "Refuse to hook int13 because of empty drive map table", [ERR_INVALID_HEADS] = "Invalid heads. Should be between 0 and 256(0 means auto)", [ERR_INVALID_SECTORS] = "Invalid sectors. Should be between 0 and 63(0 means auto)", [ERR_SPECIFY_GEOM] = "Should not specify geometry when mapping a whole drive or when emulating a hard disk with a logical partition", [ERR_EXTENDED_PARTITION] = "Extended partition table is invalid, or its CHS values conflict with the BPB in a logical partition", [ERR_DEL_MEM_DRIVE] = "You should delete other mem drive first, or use `--mem' option to force the deletion", [ERR_SPECIFY_MEM] = "Should not specify `--mem' when mapping a whole drive", [ERR_SPECIFY_RESTRICTION] = "Options --read-only, --fake-write and --unsafe-boot are mutually exclusive. Should not specify them repeatedly.", [ERR_INVALID_FLOPPIES] = "Invalid floppies. Should be between 0 and 2", [ERR_INVALID_HARDDRIVES] = "Invalid harddrives. Should be between 0 and 127", [ERR_INVALID_LOAD_SEGMENT] = "Invalid load segment. Should be between 0 and 0x9FFF", [ERR_INVALID_LOAD_OFFSET] = "Invalid load offset. Should be between 0 and 0xFFFF", [ERR_INVALID_LOAD_LENGTH] = "Invalid load length. Should be between 512 and 0xA0000", [ERR_INVALID_SKIP_LENGTH] = "Invalid skip length. Should be non-negative and less than the file size", [ERR_INVALID_BOOT_CS] = "Invalid boot CS. Should be between 0 and 0xFFFF", [ERR_INVALID_BOOT_IP] = "Invalid boot IP. Should be between 0 and 0xFFFF", [ERR_INVALID_RAM_DRIVE] = "Invalid ram_drive. Should be between 0 and 254",// [ERR_INVALID_RD_BASE] = "Invalid rd_base. Should not be 0xffffffff",// [ERR_INVALID_RD_SIZE] = "Invalid rd_size. Should not be 0", [ERR_MD_BASE] = "When mapping whole mem device at a fixed location, you must specify --mem to a value > 0.", [ERR_RD_BASE] = "RD_BASE must be sector-aligned and non-zero for mapping at a fixed location", [ERR_DOS_BACKUP] = "GRUB was not booted from DOS, or the backup copy of DOS at physical\naddress 0x200000 is corrupt", [ERR_ENABLE_A20] = "Failed to turn on Gate A20!", [ERR_DISABLE_A20] = "Failed to turn off Gate A20!", [ERR_DEFAULT_FILE] = "Invalid DEFAULT file format. Please copy a valid DEFAULT file from the grub4dos release and try again. Also note that the DEFAULT file must be uncompressed.", [ERR_PARTITION_TABLE_FULL] = "Cannot use --in-situ because the partition table is full(i.e., all the 4 entries are in use).", [ERR_MD5_FORMAT] = "Unrecognized md5 string. You must create it using the MD5CRYPT command.",};/* static for BIOS memory map fakery */static struct AddrRangeDesc fakemap[3] ={ {20, 0, 0, MB_ARD_MEMORY}, {20, 0x100000, 0, MB_ARD_MEMORY}, {20, 0x1000000, 0, MB_ARD_MEMORY}};/* A big problem is that the memory areas aren't guaranteed to be: (1) contiguous, (2) sorted in ascending order, or (3) non-overlapping. Thus this kludge. */static unsigned longmmap_avail_at (unsigned long bottom){ unsigned long long top; unsigned long addr; int cont; top = bottom; do { for (cont = 0, addr = saved_mmap_addr; addr < saved_mmap_addr + saved_mmap_length; addr += *((unsigned long *) addr) + 4) { struct AddrRangeDesc *desc = (struct AddrRangeDesc *) addr; if (desc->Type == MB_ARD_MEMORY && desc->BaseAddr <= top && desc->BaseAddr + desc->Length > top) { top = desc->BaseAddr + desc->Length; cont++; } } } while (cont); /* For now, GRUB assumes 32bits addresses, so... */ if (top > 0xFFFFFFFF) top = 0xFFFFFFFF; return (unsigned long) top - bottom;}#endif /* ! STAGE1_5 *//* This queries for BIOS information. */voidinit_bios_info (void){#ifndef STAGE1_5 unsigned long cont, memtmp, addr; int drive;#endif /* * Get information from BIOS on installed RAM. */#ifndef STAGE1_5 DEBUG_SLEEP printf("\rGet lower memory... ");#endif saved_mem_lower = get_memsize (0); /* int12 --------safe enough */#ifndef STAGE1_5 printf("\rGet upper memory... ");#endif saved_mem_upper = get_memsize (1); /* int15/88 -----safe enough */#ifndef STAGE1_5 /* * We need to call this somewhere before trying to put data * above 1 MB, since without calling it, address line 20 will be wired * to 0. Not too desirable. */#ifndef GRUB_UTIL debug = debug_boot + 1; DEBUG_SLEEP printf("\rTurning on gate A20... ");#if 1 { unsigned long j; int wait; int time1; int time2; if (gateA20 (1)) /* int15/24 -----safe enough */ { /* wipe out the messages on success */ printf("\r \r"); wait = 0; /* sleep 0 second after A20 control */ } else { printf("Failure! Report bug, please!\n"); wait = 5; /* sleep 5 second on failure */ } /* Get current time. */ while ((time2 = getrtsecs ()) == 0xFF); for (j = 0; j < 0x00800000; j++) { if ((time1 = getrtsecs ()) != time2 && time1 != 0xFF) { if (wait == 0) break; time2 = time1; wait--; } } }#else extern void grub2_gate_a20 (int on); grub2_gate_a20 (1); printf("\r \r"); /* wipe out the messages */#endif DEBUG_SLEEP#endif /* Store the size of extended memory in EXTENDED_MEMORY, in order to tell it to non-Multiboot OSes. */ extended_memory = saved_mem_upper; /* * The MBI.MEM_UPPER variable only recognizes upper memory in the * first memory region. If there are multiple memory regions, * the rest are reported to a Multiboot-compliant OS, but otherwise * unused by GRUB. */ addr = get_code_end (); saved_mmap_addr = addr; saved_mmap_length = 0; cont = 0; printf("\rGet E820 memory... "); do { cont = get_mmap_entry ((void *) addr, cont); /* int15/e820 ------ will write memory! */ /* If the returned buffer's length is zero, quit. */ if (! *((unsigned long *) addr)) break; saved_mmap_length += *((unsigned long *) addr) + 4; addr += *((unsigned long *) addr) + 4; } while (cont); if (! (saved_mmap_length)) printf("\rGet E801 memory... "); if (saved_mmap_length) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -