📄 common.c
字号:
unsigned long long max_addr; /* * This is to get the lower memory, and upper memory (up to the * first memory hole), into the MBI.MEM_{LOWER,UPPER} * elements. This is for OS's that don't care about the memory * map, but might care about total RAM available. */ saved_mem_lower = mmap_avail_at (0) >> 10; saved_mem_upper = mmap_avail_at (0x100000) >> 10; /* Find the maximum available address. Ignore any memory holes. */ for (max_addr = 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->Length > 0 && desc->BaseAddr + desc->Length > max_addr) max_addr = desc->BaseAddr + desc->Length; } extended_memory = (max_addr - 0x100000) >> 10; } else if ((memtmp = get_eisamemsize ()) != -1) /* int15/e801 ------safe enough */ { cont = memtmp & ~0xFFFF; memtmp = memtmp & 0xFFFF; if (cont != 0) extended_memory = (cont >> 10) + 0x3c00; else extended_memory = memtmp; if (!cont || (memtmp == 0x3c00)) memtmp += (cont >> 10); else { /* XXX should I do this at all ??? */ saved_mmap_addr = (unsigned long) fakemap; saved_mmap_length = sizeof (fakemap); fakemap[0].Length = (saved_mem_lower << 10); fakemap[1].Length = (memtmp << 10); fakemap[2].Length = cont; } saved_mem_upper = memtmp; } printf("\r \r"); /* wipe out the messages */ mbi.mem_upper = saved_mem_upper; mbi.mem_lower = saved_mem_lower; mbi.mmap_addr = saved_mmap_addr; mbi.mmap_length = saved_mmap_length;#ifndef GRUB_UTIL is64bit = check_64bit ();#endif /* Get the drive info. */ /* FIXME: This should be postponed until a Multiboot kernel actually requires it, because this could slow down the start-up unreasonably. */ mbi.drives_length = 0; mbi.drives_addr = addr; /* For now, GRUB doesn't probe floppies, since it is trivial to map floppy drives to BIOS drives. */#ifdef GRUB_UTIL#define FIND_DRIVES 8#else#define FIND_DRIVES (*((char *)0x475))#endif if (debug > 1) grub_printf ("hard drives: %d, int13: %X, int15: %X\n", FIND_DRIVES, *(unsigned long *)0x4C, *(unsigned long *)0x54); DEBUG_SLEEP for (drive = 0x80; drive < 0x80 + FIND_DRIVES; drive++) {#undef FIND_DRIVES struct drive_info *info = (struct drive_info *) addr;// unsigned short *port; /* Get the geometry. This ensures that the drive is present. */ if (debug > 1) grub_printf ("get_diskinfo(%X), ", drive); if (get_diskinfo (drive, &tmp_geom)) continue;//break; if (debug > 1) grub_printf (" %sC/H/S=%d/%d/%d, Sector Count/Size=%d/%d\n", (tmp_geom.flags & BIOSDISK_FLAG_LBA_EXTENSION) ? "LBA, " : "", tmp_geom.cylinders, tmp_geom.heads, tmp_geom.sectors, tmp_geom.total_sectors, tmp_geom.sector_size); // /* Clean out the I/O map. */// grub_memset ((char *) io_map, 0, IO_MAP_SIZE * sizeof (unsigned short)); /* Set the information. */ info->drive_number = drive; info->drive_mode = ((tmp_geom.flags & BIOSDISK_FLAG_LBA_EXTENSION) ? MB_DI_LBA_MODE : MB_DI_CHS_MODE); info->drive_cylinders = tmp_geom.cylinders; info->drive_heads = tmp_geom.heads; info->drive_sectors = tmp_geom.sectors; addr += sizeof (struct drive_info);// for (port = io_map; *port; port++, addr += sizeof (unsigned short))// *((unsigned short *) addr) = *port; info->size = addr - (unsigned long) info; mbi.drives_length += info->size; } init_free_mem_start = addr; DEBUG_SLEEP /* * Initialize other Multiboot Info flags. */ mbi.flags = (MB_INFO_MEMORY | MB_INFO_CMDLINE | MB_INFO_BOOTDEV | MB_INFO_DRIVE_INFO | MB_INFO_CONFIG_TABLE | MB_INFO_BOOT_LOADER_NAME); if (saved_mmap_length) mbi.flags |= MB_INFO_MEM_MAP; #endif /* STAGE1_5 */#if !defined(STAGE1_5) && !defined(GRUB_UTIL) /* Set cdrom drive. */ /* Get the geometry. */ if (debug > 1) printf("boot drive=%X, ", boot_drive); cdrom_drive = get_cdinfo (boot_drive, &tmp_geom); if (! cdrom_drive || cdrom_drive != boot_drive) cdrom_drive = GRUB_INVALID_DRIVE; if (debug > 1) printf("%s\n", cdrom_drive == GRUB_INVALID_DRIVE ? "Not CD":"Is CD"); DEBUG_SLEEP#endif #if !defined(STAGE1_5) && !defined(GRUB_UTIL) if (cdrom_drive == GRUB_INVALID_DRIVE) { int err; int version; struct drive_parameters *drp = (struct drive_parameters *)0x600;#ifdef GRUB_UTIL#define FIND_DRIVES 8#else#define FIND_DRIVES (*((char *)0x475))#endif for (drive = 0xFF; drive >= 0x7F; drive--) { if (drive >= 0x80 && drive < 0x80 + FIND_DRIVES) continue; /* Get the geometry. */ if (debug > 1) grub_printf ("\rget_cdinfo(%X),", drive); cdrom_drive = get_cdinfo (drive, &tmp_geom); if (cdrom_drive) { if (drive != 0x7F) break; drive = cdrom_drive; cdrom_drive = get_cdinfo (drive, &tmp_geom); if (cdrom_drive == drive) break; drive = 0x7F; } cdrom_drive = GRUB_INVALID_DRIVE; /* Some buggy BIOSes will hang at EBIOS `Get Drive Parameters' call * (INT 13h function 48h). So we only do further checks for Bochs. */ if (bios_id != 1) /* if it is not Bochs ... */ continue; /* ... skip and try next drive. */ /* When qemu has a cdrom attached but not booted from cdrom, its * `get bootable cdrom status call', the int13/ax=4B01, returns CF=0 * but with a wrong `Bootable CD-ROM Specification Packet' as follows: * * The first byte(packet size) is 0x13, all the rest bytes are 0's. * * So we need to call get_diskinfo() here as a workaround. * * (The bug was reported by Jacopo Lazzari. Thanks!) */ if (drive >= 0x80) { version = check_int13_extensions (drive); if (! (version & 1)) /* not support functions 42h-44h, 47h-48h */ continue; /* failure, try next drive. */ /* It is safe to clear out DRP. */ grub_memset (drp, 0, sizeof (struct drive_parameters)); drp->size = sizeof (struct drive_parameters) - 16; err = biosdisk_int13_extensions (0x4800, drive, drp); if (! err && drp->bytes_per_sector == ISO_SECTOR_SIZE) { /* Assume it is CDROM. */ cdrom_drive = drive; break; } } /* if (drive >= 0x80) */ } /* for (drive = 0x7F; drive < 0xff; drive++) */ } /* if (cdrom_drive == GRUB_INVALID_DRIVE) */#undef FIND_DRIVES if (debug > 1) grub_printf(" cdrom_drive == %X.\n", cdrom_drive); DEBUG_SLEEP#endif /* ! STAGE1_5 && ! GRUB_UTIL */ /* check if the no-emulation-mode bootable cdrom exists. */ /* if cdrom_drive is active, we assume it is the boot device */ if (saved_entryno == 0 && force_cdrom_as_boot_device) force_cdrom_as_boot_device = 0; if (cdrom_drive != GRUB_INVALID_DRIVE && force_cdrom_as_boot_device) { boot_drive = cdrom_drive; /* force it to be the boot drive */ } if (boot_drive == cdrom_drive) /* force it to be "whole drive" without partition table */ install_partition = 0xFFFFFF; /* Set boot drive and partition. */ saved_drive = boot_drive; saved_partition = install_partition;#ifndef GRUB_UTIL#ifndef STAGE1_5 debug = 1; min_cdrom_id = (cdrom_drive < 0xE0 && cdrom_drive >= 0xC0) ? 0xE0 : 0xC0; /* if grub.exe is booted as a Linux kernel, check the initrd disk. */ /* the real mode zero page(only the beginning 2 sectors, the boot params) is loaded at 0xA00 */ /* check the header signature "HdrS" (0x53726448) */ ram_drive = 0x7f; /* the default ram_drive is a floppy. */ if (*(unsigned long*)(int*)(0xA00 + 0x202) == 0x53726448) { unsigned long initrd_addr; unsigned long initrd_size; initrd_addr = *(unsigned long*)(int*)(0xA00 + 0x218); initrd_size = *(unsigned long*)(int*)(0xA00 + 0x21c); if (initrd_addr && initrd_size) { rd_base = initrd_addr; rd_size = initrd_size; /* check if there is a partition table */ if (*(unsigned short *)(initrd_addr + 0x40) == 0xAA55) { if (! probe_mbr ((struct master_and_dos_boot_sector *)initrd_addr, 0, initrd_size, 0)) ram_drive = 0xfe; /* partition table is valid, so let it be a harddrive */ else grub_printf ("\nUnrecognized partition table for RAM DRIVE; assuming floppy. Please rebuild\nit using a Microsoft-compatible FDISK tool, if the INITRD is a hard-disk image.\n"); } } }#endif /* ! STAGE1_5 */#endif /* ! GRUB_UTIL */ /* Start main routine here. */ grub_printf("Starting cmain() ... "); #if !defined(STAGE1_5) && !defined(GRUB_UTIL) DEBUG_SLEEP#endif /* ! STAGE1_5 && ! GRUB_UTIL */// cmain (); /* moved into asm.S and asmstub.c */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -