📄 grub-0.95-patch4-emulation
字号:
+ else+ grub_printf ("%s%d[0-%d]", num_entries ? "," : "", start_sector - part_start, last_length);+ } num_entries++; num_sectors = 0; }@@ -172,6 +200,7 @@ if (offset > 0) {+ if (query_block_entries >= 0) grub_printf("%s%d[%d-%d]", num_entries ? "," : "", sector-part_start, offset, offset+length); num_entries++;@@ -184,39 +213,89 @@ } } + map_start_sector = 0;+ map_num_sectors = 0;+ /* Open the file. */ if (! grub_open (arg))- return 1;+ goto fail_open; /* 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 (")"); + rawread_ignore_memmove_overflow = 1; /* Read in the whole file to DUMMY. */ disk_read_hook = disk_read_blocklist_func;- if (! grub_read (dummy, -1))- goto fail;+ err = grub_read (dummy, query_block_entries < 0 ? SECTOR_SIZE : -1);+ disk_read_hook = 0;+ rawread_ignore_memmove_overflow = 0;+ if (! err)+ goto fail_read; /* 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 (num_sectors > 0)- grub_printf ("%s%d+%d", num_entries ? "," : "",+ {+ if (query_block_entries >= 0)+ grub_printf ("%s%d+%d", num_entries ? "," : "", start_sector - part_start, num_sectors);+ num_entries++;+ } - grub_printf ("\n");- - fail:- disk_read_hook = 0;+ if (query_block_entries >= 0)+ grub_printf ("\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 = start_sector;+ start_sector = 0;+ num_sectors = 0;+ num_entries = 0;+ last_length = 0;+ rawread_ignore_memmove_overflow = 1;+ /* read in the last sector to DUMMY */+ filepos = filemax ? (filemax - 1) & (-SECTOR_SIZE) : filemax;+ disk_read_hook = disk_read_blocklist_func;+ err = grub_read (dummy, -1);+ disk_read_hook = 0;+ rawread_ignore_memmove_overflow = 0;+ if (! err)+ goto fail_read;+ map_num_sectors = start_sector - map_start_sector + 1;+ query_block_entries = filemax ? + map_num_sectors - ((filemax - 1) >> SECTOR_BITS) : 2;+//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);+ }++fail_read: grub_close ();+fail_open:+ if (query_block_entries < 0)+ query_block_entries = 0; return errnum; } @@ -266,19 +345,20 @@ /* Chainloader */ /* Check if we should set the int13 handler. */- if (bios_drive_map[0] != 0)+ if (! int13_on_hook && ! drive_map_slot_empty (bios_drive_map[0])) { int i; /* Search for SAVED_DRIVE. */ for (i = 0; i < DRIVE_MAP_SIZE; i++) {- if (! bios_drive_map[i])+ if (drive_map_slot_empty (bios_drive_map[i])) break;- else if ((bios_drive_map[i] & 0xFF) == saved_drive)+ if ((bios_drive_map[i].from_drive) == saved_drive) {- /* Exchage SAVED_DRIVE with the mapped drive. */- saved_drive = (bios_drive_map[i] >> 8) & 0xFF;+ /* Exchage SAVED_DRIVE with the mapped drive, only if the whole drive is mapped. */+ if (! bios_drive_map[i].start_sector && ! (bios_drive_map[i].sector_count >> 1))+ saved_drive = bios_drive_map[i].to_drive; break; } }@@ -448,8 +528,9 @@ if (IS_PC_SLICE_TYPE_FAT (current_slice) && ! grub_memcmp ((char *) BOOTSEC_LOCATION + BOOTSEC_BPB_SYSTEM_ID, "MSWIN", 5))- *((unsigned long *) (BOOTSEC_LOCATION + BOOTSEC_BPB_HIDDEN_SECTORS))- = part_start;+ if (*((unsigned long *) (BOOTSEC_LOCATION + BOOTSEC_BPB_HIDDEN_SECTORS)))+ *((unsigned long *) (BOOTSEC_LOCATION + BOOTSEC_BPB_HIDDEN_SECTORS))+ = part_start; errnum = ERR_NONE; @@ -2479,31 +2560,805 @@ char *to_drive; char *from_drive; unsigned long to, from;- int i;+ int i, j;+ unsigned long start_sector, sector_count;+ char *filename;+ char *p;+ unsigned long extended_part_start;+ unsigned long extended_part_length;+ struct master_and_dos_boot_sector {+/* 00 */ char dummy1[0x0b]; /* at offset 0, normally there is a short JMP instuction(opcode is 0xEB) */+/* 0B */ unsigned short bytes_per_sector __attribute__ ((packed));/* seems always to be 512, so we just use 512 */+/* 0D */ unsigned char sectors_per_cluster __attribute__ ((packed));/* non-zero, the power of 2, i.e., 2^n */+/* 0E */ unsigned short reserved_sectors __attribute__ ((packed));/* non-zero */+/* 10 */ unsigned char number_of_fats __attribute__ ((packed));/* NTFS=0; FAT=1 or 2 */+/* 11 */ unsigned short root_dir_entries __attribute__ ((packed));/* FAT32=0, NTFS=0, FAT12/16=non-zero */+/* 13 */ unsigned short total_sectors_short __attribute__ ((packed));/* FAT32=0, NTFS=0, FAT12/16=any */+/* 15 */ unsigned char media_descriptor __attribute__ ((packed));/* range from 0xf0 to 0xff */+/* 16 */ unsigned short sectors_per_fat __attribute__ ((packed));/* FAT32=0, NTFS=0, FAT12/16=non-zero */+/* 18 */ unsigned short sectors_per_track __attribute__ ((packed));/* range from 1 to 63 */+/* 1A */ unsigned short total_heads __attribute__ ((packed));/* range from 1 to 256 */+/* 1C */ unsigned long hidden_sectors __attribute__ ((packed));/* any value */+/* 20 */ unsigned long total_sectors_long __attribute__ ((packed));/* FAT32=non-zero, NTFS=0, FAT12/16=any */+/* 24 */ unsigned long sectors_per_fat32 __attribute__ ((packed));/* FAT32=non-zero, NTFS=0, FAT12/16=any */+/* 28 */ unsigned long long total_sectors_long_long __attribute__ ((packed));/* NTFS=non-zero, FAT12/16/32=any */+/* 30 */ char dummy2[0x30] __attribute__ ((packed));++ /* This starts at offset 0x60 */+/* 60 */ unsigned long probed_total_sectors __attribute__ ((packed));+/* 64 */ unsigned long probed_heads __attribute__ ((packed));+/* 68 */ unsigned long probed_sectors_per_track __attribute__ ((packed));+/* 6C */ unsigned long probed_cylinders __attribute__ ((packed));+/* 70 */ unsigned long sectors_per_cylinder __attribute__ ((packed));+/* 74 */ char dummy3[0xbc] __attribute__ ((packed));++ /* matrix of coefficients of linear equations+ * + * C[n] * (H_count * S_count) + H[n] * S_count = LBA[n] - S[n] + 1+ *+ * where n = 1, 2, 3, 4, 5, 6, 7, 8+ */+ /* This starts at offset 0x130 */ +/* 130 */ long long L[9] __attribute__ ((packed)); /* L[n] == LBA[n] - S[n] + 1 */+/* 178 */ long H[9] __attribute__ ((packed));+/* 19C */ short C[9] __attribute__ ((packed));+/* 1AE */ short X __attribute__ ((packed));+/* 1B0 */ short Y __attribute__ ((packed));+/* 1B2 */ short Cmax __attribute__ ((packed));+/* 1B4 */ long Hmax __attribute__ ((packed));+/* 1B8 */ unsigned long Z __attribute__ ((packed));+/* 1BC */ short Smax __attribute__ ((packed));++ /* Partition Table, starting at offset 0x1BE */+/* 1BE */ struct {+ /* +00 */ unsigned char boot_indicator __attribute__ ((packed));+ /* +01 */ unsigned char start_head __attribute__ ((packed));+ /* +02 */ unsigned short start_sector_cylinder __attribute__ ((packed));+ /* +04 */ unsigned char system_indicator __attribute__ ((packed));+ /* +05 */ unsigned char end_head __attribute__ ((packed));+ /* +06 */ unsigned short end_sector_cylinder __attribute__ ((packed));+ /* +08 */ unsigned long start_lba __attribute__ ((packed));+ /* +0C */ unsigned long total_sectors __attribute__ ((packed));+ /* +10 */+ } P[4] __attribute__ ((packed));+/* 1FE */ unsigned short boot_signature __attribute__ ((packed));/* 0xAA55 */+/* 200 */+ };++ struct master_and_dos_boot_sector *BS = (struct master_and_dos_boot_sector *) RAW_ADDR (0x100000);++ int read_only = 0;+ int fake_write = 0;+ int unsafe_boot = 0;+ int disable_lba_mode = 0;+ int disable_chs_mode = 0;+ int sectors_per_track = -1;+ int heads_per_cylinder = -1;+ unsigned long BPB_H = 0;+ unsigned long BPB_S = 0;+ start_sector = sector_count = 0;+#if 0 + grub_printf ("sizeof(struct master_and_dos_boot_sector)=%d\n", sizeof(struct master_and_dos_boot_sector));+ return 0;+#endif+ for (;;)+ {+ if (grub_memcmp (arg, "--status", 8) == 0)+ {+ if (! int13_on_hook && drive_map_slot_empty (bios_drive_map[0]))+ {+ grub_printf ("\nThe int13 hook is off. The drive map table is currently empty.\n");+ return 0;+ }+ /* From To MaxHead MaxSector StartLBA Sector_count Hook */+ grub_printf ("\nFr To Hm Sm StartLBA #Sectors Hk\n"+ "-- -- -- -- -------- -------- --\n");+ if (int13_on_hook)+ for (i = 0; i < DRIVE_MAP_SIZE; i++)+ {+ if (drive_map_slot_empty (hooked_drive_map[i]))+ break;+ for (j = 0; j < DRIVE_MAP_SIZE; j++)+ {+ if (drive_map_slot_equal(bios_drive_map[j], hooked_drive_map[i]))+ break;+ }+ grub_printf ("%X%X %X%X %X%X %X%X %X%X%X%X%X%X%X%X %X%X%X%X%X%X%X%X 1%d\n", hooked_drive_map[i].from_drive>>4, hooked_drive_map[i].from_drive & 0x0f, hooked_drive_map[i].to_drive>>4, hooked_drive_map[i].to_drive & 0x0f, hooked_drive_map[i].max_head>>4, hooked_drive_map[i].max_head & 0x0f, hooked_drive_map[i].max_sector>>4, hooked_drive_map[i].max_sector & 0x0f, hooked_drive_map[i].start_sector>>28, (hooked_drive_map[i].start_sector>>24) & 0x0f, (hooked_drive_map[i].start_sector>>20) & 0x0f, (hooked_drive_map[i].start_sector>>16) & 0x0f, (hooked_drive_map[i].start_sector>>12) & 0x0f, (hooked_drive_map[i].start_sector>>8) & 0x0f, (hooked_drive_map[i].start_sector>>4) & 0x0f, hooked_drive_map[i].start_sector & 0x0f, hooked_drive_map[i].sector_count>>28, (hooked_drive_map[i].sector_count>>24) & 0x0f, (hooked_drive_map[i].sector_count>>20) & 0x0f, (hooked_drive_map[i].sector_count>>16) & 0x0f, (hooked_drive_map[i].sector_count>>12) & 0x0f, (hooked_drive_map[i].sector_count>>8) & 0x0f, (hooked_drive_map[i].sector_count>>4) & 0x0f, hooked_drive_map[i].sector_count & 0x0f, (j < DRIVE_MAP_SIZE));+ }+ for (i = 0; i < DRIVE_MAP_SIZE; i++)+ {+ if (drive_map_slot_empty (bios_drive_map[i]))+ break;+ if (int13_on_hook)+ {+ for (j = 0; j < DRIVE_MAP_SIZE; j++)+ {+ if (drive_map_slot_equal(hooked_drive_map[j], bios_drive_map[i]))+ break;+ }+ if (j < DRIVE_MAP_SIZE)+ continue;+ }+ grub_printf ("%X%X %X%X %X%X %X%X %X%X%X%X%X%X%X%X %X%X%X%X%X%X%X%X 01\n", bios_drive_map[i].from_drive>>4, bios_drive_map[i].from_drive & 0x0f, bios_drive_map[i].to_drive>>4, bios_drive_map[i].to_drive & 0x0f, bios_drive_map[i].max_head>>4, bios_drive_map[i].max_head & 0x0f, bios_drive_map[i].max_sector>>4, bios_drive_map[i].max_sector & 0x0f, bios_drive_map[i].start_sector>>28, (bios_drive_map[i].start_sector>>24) & 0x0f, (bios_drive_map[i].start_sector>>20) & 0x0f, (bios_drive_map[i].start_sector>>16) & 0x0f, (bios_drive_map[i].start_sector>>12) & 0x0f, (bios_drive_map[i].start_sector>>8) & 0x0f, (bios_drive_map[i].start_sector>>4) & 0x0f, bios_drive_map[i].start_sector & 0x0f, bios_drive_map[i].sector_count>>28, (bios_drive_map[i].sector_count>>24) & 0x0f, (bios_drive_map[i].sector_count>>20) & 0x0f, (bios_drive_map[i].sector_count>>16) & 0x0f, (bios_drive_map[i].sector_count>>12) & 0x0f, (bios_drive_map[i].sector_count>>8) & 0x0f, (bios_drive_map[i].sector_count>>4) & 0x0f, bios_drive_map[i].sector_count & 0x0f);+ }++ return 0;+ }+ else if (grub_memcmp (arg, "--hook", 6) == 0)+ {+ if (int13_on_hook)+ return errnum = ERR_INT13_ON_HOOK;+ if (drive_map_slot_empty (bios_drive_map[0]))+ return errnum = ERR_NO_DRIVE_MAPPED;+ set_int13_handler (bios_drive_map);+ int13_on_hook = 1;+ return 0;+ }+ else if (grub_memcmp (arg, "--unhook", 8) == 0)+ {+ if (! int13_on_hook)+ return errnum = ERR_INT13_OFF_HOOK;+ unset_int13_handler ();+ int13_on_hook = 0;+ return 0;+ }+ else if (grub_memcmp (arg, "--rehook", 8) == 0)+ {+ if (! int13_on_hook)+ return errnum = ERR_INT13_OFF_HOOK;+ unset_int13_handler ();+ int13_on_hook = 0;+ if (drive_map_slot_empty (bios_drive_map[0]))+ return errnum = ERR_NO_DRIVE_MAPPED;+ set_int13_handler (bios_drive_map);+ int13_on_hook = 1;+ return 0;+ }+ else if (grub_memcmp (arg, "--read-only", 11) == 0)+ {+ read_only = 1;+ }+ else if (grub_memcmp (arg, "--fake-write", 12) == 0)+ {+ fake_write = 1;+ }+ else if (grub_memcmp (arg, "--unsafe-boot", 13) == 0)+ {+ unsafe_boot = 1;+ }+ else if (grub_memcmp (arg, "--disable-chs-mode", 18) == 0)+ {+ disable_chs_mode = 1;+ }+ else if (grub_memcmp (arg, "--disable-lba-mode", 18) == 0)+ {+ disable_lba_mode = 1;+ }+ else if (grub_memcmp (arg, "--heads-per-cylinder=", 21) == 0)+ {+ p = arg + 21;+ if (! safe_parse_maxint (&p, &heads_per_cylinder))+ return 1;+ if (heads_per_cylinder < 0 || heads_per_cylinder > 256)+ return errnum = ERR_INVALID_HEADS;+ }+ else if (grub_memcmp (arg, "--sectors-per-track=", 20) == 0)+ {+ p = arg + 20;+ if (! safe_parse_maxint (&p, §ors_per_track))+ return 1;+ if (sectors_per_track < 0 || sectors_per_track > 63)+ return errnum = ERR_INVALID_SECTORS;+ }+ else+ break;+ arg = skip_to (0, arg);+ } 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; + /* Get the drive number for TO_DRIVE. */+ filename = set_device (to_drive);+//grub_printf ("x: to=0x%x, current_drive=0x%x, current_partition=0x%x, saved_drive=0x%x, saved_partition=0x%x, errnum=%d\n", to, current_drive, current_partition, saved_drive, saved_partition, errnum);++ if (errnum) {+ /* No device specified. Default to the root device. */+ current_drive = saved_drive;+ //current_partition = saved_partition;+ filename = 0;+ errnum = 0;+ }+ + to = current_drive;+//grub_printf ("0: part_start=%d, part_length=%d\n", part_start, part_length);++ if (current_partition == 0xFFFFFF && filename && (*filename == 0x20 || *filename == 0x09))+ {+ /* when whole drive is mapped, the geometry should not be specified. */+ if (heads_per_cylinder > 0 || sectors_per_track > 0)+ return errnum = ERR_SPECIFY_GEOM;++ sectors_per_track = 1;/* 1 means the specified geometry will be ignored. */+ heads_per_cylinder = 1;/* can be any value but ignored since #sectors==1. */+ /* Note: if the user do want to specify geometry for whole drive map, then+ * use a command like this:+ * + * map --heads-per-cylinder=H --sectors-per-track=S (hd0)+1 (hd1)+ * + * where S > 1+ */+ goto map_whole_drive;+ }++ query_block_entries = -1; /* query block list only */+ blocklist_func (to_drive, flags);+//grub_printf ("1: part_start=%d, part_length=%d\n", part_start, part_length);+//grub_printf (", errnum=%d, query_block_entries=%d,map_start_sector=%d,map_num_sectors=%d,sizeof (struct drive_map_slot)=%d\n", errnum, query_block_entries, map_start_sector, map_num_sectors, sizeof (struct drive_map_slot));+ if (errnum == 0)+ {+ if (query_block_entries == 1)+ {+ start_sector = map_start_sector;+ sector_count = map_num_sectors;+ }+ else //if (query_block_entries > 1)+ {+ return errnum = ERR_NON_CONTIGUOUS;+ }+ //else+ //return errnum;+ }+ else+ return errnum;++ if (start_sector == part_start && part_start && sector_count == 1)+ sector_count = part_length;++//grub_printf ("2: part_start=%d, part_length=%d\n", part_start, part_length);+ if (! grub_open (to_drive))+ return 1;+//grub_printf ("3: part_start=%d, part_length=%d\n", part_start, part_length);++ /* Read the first sector of the emulated disk. */+ if (grub_read ((char *) BS, SECTOR_SIZE) != SECTOR_SIZE)+ {+ grub_close ();++ /* This happens, if the file size is less than 512 bytes. */+ if (errnum == ERR_NONE)+ errnum = ERR_EXEC_FORMAT;+
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -