📄 grub-0.95-patch4-emulation
字号:
+ return 1;+ }+ grub_close ();+//grub_printf ("4: part_start=%d, part_length=%d\n", part_start, part_length);++ if (BS->boot_signature != 0xAA55)+ goto geometry_probe_failed;+ /* probe the BPB */+ BS->probed_total_sectors = BS->total_sectors_short ? BS->total_sectors_short : (BS->total_sectors_long ? BS->total_sectors_long : (unsigned long)BS->total_sectors_long_long);+// if (sector_count == 1)+// sector_count = BS->probed_total_sectors;+ if (BS->probed_total_sectors != sector_count && sector_count != 1 && (! (BS->probed_total_sectors & 1) || BS->probed_total_sectors != sector_count - 1))+ goto failed_probe_BPB;+ if (BS->bytes_per_sector != 0x200)+ goto failed_probe_BPB;+ if (! BS->sectors_per_cluster || 128 % BS->sectors_per_cluster)+ goto failed_probe_BPB;+ if (! BS->reserved_sectors)+ goto failed_probe_BPB;+ if (BS->number_of_fats && ((BS->number_of_fats - 1) >> 1))+ goto failed_probe_BPB;+ if (! BS->sectors_per_track || BS->sectors_per_track > 63)+ goto failed_probe_BPB;+ if ((BS->total_heads - 1) >> 8)+ goto failed_probe_BPB;+ if (BS->media_descriptor < 0xF0)+ goto failed_probe_BPB;+ if (! BS->root_dir_entries && ! BS->total_sectors_short && ! BS->sectors_per_fat) /* FAT32 or NTFS */+ if (BS->number_of_fats && BS->total_sectors_long && BS->sectors_per_fat32)+ grub_printf ("FAT32 ");+ else if (! BS->number_of_fats && ! BS->total_sectors_long && ! BS->sectors_per_fat32 && BS->total_sectors_long_long)+ grub_printf ("NTFS ");+ else+ goto failed_probe_BPB; /* unknown NTFS-style BPB */+ else if (BS->number_of_fats && BS->sectors_per_fat) /* FAT12 or FAT16 */+ if ((BS->probed_total_sectors - BS->reserved_sectors - BS->number_of_fats * BS->sectors_per_fat - (BS->root_dir_entries * 32 + BS->bytes_per_sector - 1) / BS->bytes_per_sector) / BS->sectors_per_cluster < 0x0ff8 )+ grub_printf ("FAT12 ");+ else+ grub_printf ("FAT16 ");+ else+ goto failed_probe_BPB;+ if (BS->dummy1[0] == (char)0xEB) /* the short jump instruction */+ grub_printf ("BPB found with the starting 0xEB (jmp) confirmation.\n");+ else+ grub_printf ("BPB found WITHOUT the starting 0xEB (jmp) confirmation.\n");+ + BS->probed_heads = BS->total_heads;+ BS->probed_sectors_per_track = BS->sectors_per_track;+ BS->sectors_per_cylinder = BS->probed_heads * BS->probed_sectors_per_track;+ BS->probed_cylinders = BS->probed_total_sectors / BS->sectors_per_cylinder;++//grub_printf ("debug info: part_start=%d, part_length=%d, start_sector=%d, sector_count=%d, from=%x, to=%x, BS->reserved_sectors=%x, BS->probed_sectors_per_track=%x\n", part_start, part_length, start_sector, sector_count, from, to, BS->hidden_sectors, BS->probed_sectors_per_track);+ if ((from & 0x80) && (to & 0x80) && (start_sector == part_start && part_start && sector_count == part_length) && BS->hidden_sectors >= BS->probed_sectors_per_track)+ {+ extended_part_start = BS->hidden_sectors - BS->probed_sectors_per_track;+ extended_part_length = BS->probed_total_sectors + BS->probed_sectors_per_track;+ grub_printf ("\nBPB probed C/H/S = %d/%d/%d, BPB probed total sectors = %d\n", BS->probed_cylinders, BS->probed_heads, BS->probed_sectors_per_track, BS->probed_total_sectors);+ BPB_H = BS->probed_heads;+ BPB_S = BS->probed_sectors_per_track;+ + grub_printf ("Try to locate the extended partition (hd%d)%d+%d for emulating (hd%d).\n", (to & 0x7f), extended_part_start, extended_part_length, (from & 0x7f));+ grub_sprintf ((char *)BS, "(hd%d)%d+%d", (to & 0x7f), extended_part_start, extended_part_length);+ if (! grub_open ((char *)BS))+ return 1;++ /* 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;+ + return 1;+ }+ grub_close ();+//grub_printf ("debug info: part_start=%d, part_length=%d, start_sector=%d, sector_count=%d\n", part_start, part_length, start_sector, sector_count);+ for (i = 0; i < 4; i++)+ {+ unsigned char sys = BS->P[i].system_indicator;+ if (sys == 0x05 || sys == 0x0f || sys == 0)+ {+ *(long long *)&(BS->P[i].boot_indicator) = 0LL;+ *(long long *)&(BS->P[i].start_lba) = 0LL;+ }+ }+ start_sector = part_start = extended_part_start;+ sector_count = part_length = extended_part_length;+ /* when emulating a hard disk using a logical partition, the geometry should not be specified. */+ if (heads_per_cylinder > 0 || sectors_per_track > 0)+ return errnum = ERR_SPECIFY_GEOM;++ goto failed_probe_BPB;+ }+ //if (BS->probed_cylinders * BS->sectors_per_cylinder == BS->probed_total_sectors)+ goto geometry_probe_ok;++failed_probe_BPB:+ /* probe the partition table */+ + BS->Cmax = 0; BS->Hmax = 0; BS->Smax = 0;+ for (i = 0; i < 4; i++)+ {+ if ((unsigned char)(BS->P[i].boot_indicator << 1))/* if neither 0x80 nor 0 */+ goto geometry_probe_failed;+ if (*(long long *)&(BS->P[i].boot_indicator) || *(long long *)&(BS->P[i].start_lba))+ {+ if (! BS->P[i].start_lba || ! BS->P[i].total_sectors)+ goto geometry_probe_failed;+ for (j = 0; j < i; j++)+ if ((BS->P[j].start_lba < BS->P[i].start_lba) ?+ (BS->P[i].start_lba - BS->P[j].start_lba < BS->P[j].total_sectors) :+ (BS->P[j].start_lba - BS->P[i].start_lba < BS->P[i].total_sectors))+ goto geometry_probe_failed;+ BS->C[i] = (BS->P[i].start_sector_cylinder >> 8) | ((BS->P[i].start_sector_cylinder & 0xc0) << 2);+ if (BS->Cmax < BS->C[i])+ BS->Cmax = BS->C[i];+ BS->H[i] = BS->P[i].start_head;+ if (BS->Hmax < BS->H[i])+ BS->Hmax = BS->H[i];+ BS->X = BS->P[i].start_sector_cylinder & 0x3f;+ if (BS->Smax < BS->X)+ BS->Smax = BS->X;+ if (! BS->X || BS->P[i].start_lba < BS->X - 1)+ goto geometry_probe_failed;+ BS->L[i] = BS->P[i].start_lba - BS->X + 1 + (unsigned long) part_start;+ + BS->C[i+4] = (BS->P[i].end_sector_cylinder >> 8) | ((BS->P[i].end_sector_cylinder & 0xc0) << 2);+ if (BS->Cmax < BS->C[i+4])+ BS->Cmax = BS->C[i+4];+ BS->H[i+4] = BS->P[i].end_head;+ if (BS->Hmax < BS->H[i+4])+ BS->Hmax = BS->H[i+4];+ BS->Y = BS->P[i].end_sector_cylinder & 0x3f;+ if (BS->Smax < BS->Y)+ BS->Smax = BS->Y;+ if (! BS->Y)+ goto geometry_probe_failed;+ BS->L[i+4] = BS->P[i].start_lba;+ if (BS->L[i+4] + BS->P[i].total_sectors < BS->Y)+ goto geometry_probe_failed;+ BS->L[i+4] = (BS->L[i+4] + BS->P[i].total_sectors) - BS->Y + (unsigned long) part_start;+ + /* Check the large disk partition. */+ if (BS->Y == 63 && BS->C[i+4] == 1023 && BS->H[i+4] >= 254 && BS->H[i+4] == BS->Hmax+ && 1023 * (BS->Hmax + 1) * 63 + BS->Hmax * 63 < BS->L[i+4]+ && BS->C[i] * (BS->Hmax + 1) * 63 + BS->H[i] * 63 + BS->X - 1 == BS->P[i].start_lba)+ {+ BS->C[i] = 0; BS->H[i] = 1; BS->L[i] = 63;+ BS->C[i+4] = 1; BS->H[i+4] = 0; BS->L[i+4] = (BS->Hmax + 1) * 63;+ }+ }+ else+ {+ BS->C[i] = 0;+ BS->H[i] = 0;+ BS->L[i] = 0;+ BS->C[i+4] = 0;+ BS->H[i+4] = 0;+ BS->L[i+4] = 0;+ }+ }++ for (i = 0; i < 8; i++)+ {+ if (BS->C[i])+ break;+ }+ if (i == 8) /* all C[i] == 0 */+ {+ for (i = 0; i < 8; i++)+ {+ if (BS->H[i])+ break;+ }+ if (i == 8) /* all H[i] == 0 */+ goto geometry_probe_failed;+ for (j = 0; j < i; j++)+ if (BS->L[j])+ goto geometry_probe_failed;+ if (! BS->L[i])+ goto geometry_probe_failed;+ //if (*(long *)((char *)&(BS->L[i]) + 4))+ if (BS->L[i] > 0x7fffffff)+ goto geometry_probe_failed;+ if ((long)BS->L[i] % BS->H[i])+ goto geometry_probe_failed;+ BS->probed_sectors_per_track = (long)BS->L[i] / BS->H[i];+ if (BS->probed_sectors_per_track > 63 || BS->probed_sectors_per_track < BS->Smax)+ goto geometry_probe_failed;+ for (j = i + 1; j < 8; j++)+ {+ if (BS->H[j])+ {+ if (BS->probed_sectors_per_track * BS->H[j] != BS->L[j])+ goto geometry_probe_failed;+ }+ else if (BS->L[j])+ goto geometry_probe_failed;+ }+ BS->probed_heads = BS->Hmax + 1;+#if 0+ if (sector_count == 1)+ BS->probed_cylinders = 1;+ else+#endif+ {+ BS->L[8] = sector_count; /* just set to a number big enough */+ BS->Z = sector_count / BS->probed_sectors_per_track;+ for (j = BS->probed_heads; j <= 256; j++)+ {+ BS->H[8] = BS->Z % j;/* the remainder */+ if (BS->L[8] > BS->H[8])+ {+ BS->L[8] = BS->H[8];/* the least residue */+ BS->probed_heads = j;/* we got the optimum value */+ }+ }+ BS->probed_cylinders = BS->Z / BS->probed_heads;+ if (! BS->probed_cylinders)+ BS->probed_cylinders = 1; + }+ BS->sectors_per_cylinder = BS->probed_heads * BS->probed_sectors_per_track;+ BS->probed_total_sectors = BS->sectors_per_cylinder * BS->probed_cylinders;+ }+ else+ {+ if (i > 0)+ {+ BS->C[8] = BS->C[i]; BS->H[8] = BS->H[i]; BS->L[8] = BS->L[i];+ BS->C[i] = BS->C[0]; BS->H[i] = BS->H[0]; BS->L[i] = BS->L[0];+ BS->C[0] = BS->C[8]; BS->H[0] = BS->H[8]; BS->L[0] = BS->L[8];+ }+ BS->H[8] = 0; /* stores the number of sectors per track */+ for (i = 1; i < 8; i++)+ {+ BS->H[i] = BS->C[0] * BS->H[i] - BS->C[i] * BS->H[0];+ BS->L[i] = BS->C[0] * BS->L[i] - BS->C[i] * BS->L[0];+ if (BS->H[i])+ {+ if (BS->H[i] < 0)+ {+ BS->H[i] = - BS->H[i];/* BS->H[i] < 0x080000 */+ BS->L[i] = - BS->L[i];+ if (BS->L[i] <= 0 || BS->L[i] > 0x7fffffff)+ goto geometry_probe_failed;+ }+ BS->L[8] = (long)BS->L[i] / BS->H[i]; /* sectors per track */+ if (BS->L[8] * BS->H[i] != BS->L[i])+ goto geometry_probe_failed;+ if (BS->L[8] > 63 || BS->L[8] < BS->Smax)+ goto geometry_probe_failed;+ if (BS->H[8])+ {+ /* H[8] is the old L[8] */+ if (BS->L[8] != BS->H[8])+ goto geometry_probe_failed;+ }+ else /* H[8] is empty, so store L[8] for the first time */+ BS->H[8] = BS->L[8];+ }+ else if (BS->L[i])+ goto geometry_probe_failed;+ }+ if (BS->H[8])+ {+ /* H[8] is sectors per track */+ BS->L[0] = BS->L[0] - BS->H[0] * BS->H[8];+ if (BS->L[0] <= 0 || BS->L[0] > 0x7fffffff)+ goto geometry_probe_failed;+ + /* L[8] is number of heads */+ BS->L[8] = (long)BS->L[0] / BS->H[8] / BS->C[0];+ if (BS->L[8] * BS->H[8] * BS->C[0] != BS->L[0])+ goto geometry_probe_failed;+ if (BS->L[8] > 256 || BS->L[8] <= BS->Hmax)+ goto geometry_probe_failed;+ BS->probed_sectors_per_track = BS->H[8];+ }+ else /* fail to set L[8], this means all H[i]==0, i=1,2,3,4,5,6,7 */+ {+ /* Now the only equation is: C[0] * H * S + H[0] * S = L[0] */+ for (i = 63; i >= BS->Smax; i--)+ {+ BS->L[8] = BS->L[0] - BS->H[0] * i;+ if (BS->L[8] <= 0 || BS->L[8] > 0x7fffffff)+ continue;+ BS->Z = BS->L[8];+ if (BS->Z % (BS->C[0] * i))+ continue;+ BS->L[8] = BS->Z / (BS->C[0] * i);+ if (BS->L[8] <= 256 && BS->L[8] > BS->Hmax)+ break;/* we have got the PROBED_HEADS */+ }+ if (i < BS->Smax)+ goto geometry_probe_failed;+ BS->probed_sectors_per_track = i;+ }+ BS->probed_heads = BS->L[8];+ BS->sectors_per_cylinder = BS->probed_heads * BS->probed_sectors_per_track;+ BS->probed_cylinders = sector_count / BS->sectors_per_cylinder;+ if (BS->probed_cylinders < BS->Cmax + 1)+ BS->probed_cylinders = BS->Cmax + 1;+ BS->probed_total_sectors = BS->sectors_per_cylinder * BS->probed_cylinders;+ }+ goto geometry_probe_ok;++geometry_probe_failed:++ if (BPB_H || BPB_S)+ return errnum = ERR_EXTENDED_PARTITION;+ + if (heads_per_cylinder < 0)+ {+ if (from & 0x80)+ return errnum = ERR_NO_HEADS;+ /* floppy emulation */+ switch (sector_count)+ {+ /* for the 5 standard floppy disks, offer a value */+ case 720: /* 360K */+ case 1440: /* 720K */+ case 2400: /* 1200K */+ case 2880: /* 1440K */+ case 5760: /* 2880K */+ heads_per_cylinder = 2; break;+ default:+ return errnum = ERR_NO_HEADS;+ }+ grub_printf ("\nAutodetect number-of-heads failed. Use default value %d\n", heads_per_cylinder);+ }+ else if (heads_per_cylinder == 0)+ {+ if (from & 0x80)+ {+ /* hard disk emulation */+ heads_per_cylinder = 256;+ }+ else+ {+ /* floppy emulation */+ switch (sector_count)+ {+ case 320: /* 160K */+ case 360: /* 180K */+ case 500: /* 250K */+ heads_per_cylinder = 1; break;+ case 1: /* a whole-disk emulation */+ heads_per_cylinder = 256; break;+ default:+ if (sector_count <= 63 * 1024 * 2 + 1)+ heads_per_cylinder = 2;+ else+ heads_per_cylinder = 256;+ }+ }+ grub_printf ("\nAutodetect number-of-heads failed. Use default value %d\n", heads_per_cylinder);+ }+ else+ {+ grub_printf ("\nAutodetect number-of-heads failed. Use the specified %d\n", heads_per_cylinder);+ }++ if (sectors_per_track < 0)+ {+ if (from & 0x80)+ return errnum = ERR_NO_SECTORS;+ /* floppy emulation */+ switch (sector_count)+ {+ /* for the 5 standard floppy disks, offer a value */+ case 720: /* 360K */+ case 1440: /* 720K */+ sectors_per_track = 9; break;+ case 2400: /* 1200K */+ sectors_per_track = 15; break;+ case 2880: /* 1440K */+ sectors_per_track = 18; break;+ case 5760: /* 2880K */+ sectors_per_track = 36; break;+ default:+ return errnum = ERR_NO_SECTORS;+ }+ grub_printf ("\nAutodetect sectors-per-track failed. Use default value %d\n", sectors_per_track);+ }+ else if (sectors_per_track == 0)+ {+ if (sector_count == 1)+ sectors_per_track = 1;+ else if (from & 0x80)+ {+ /* hard disk emulation */+ sectors_per_track = 63;+ }+ else+ {+ /* floppy emulation */+ switch (sector_count)+ {+ case 400: /* 200K */+ sectors_per_track = 5; break;+ case 320: /* 160K */+ case 640: /* 320K */+ case 1280: /* 640K */+ sectors_per_track = 8; break;+ case 360: /* 180K */+ case 720: /* 360K */+ case 1440: /* 720K */+ case 1458: /* 729K */+ case 1476: /* 738K */+ case 1494: /* 747K */+ case 1512: /* 756K */+ sectors_per_track = 9; break;+ case 500: /* 250K */+ case 800: /* 400K */+ case 840: /* 420K */+ case 1000: /* 500K */+ case 1600: /* 800K */+ case 1620: /* 810K */+ case 1640: /* 820K */+ case 1660: /* 830K */+ case 1680: /* 840K */+ sectors_per_track = 10; break;+ case 1804: /* 902K */+ sectors_per_track = 11; break;+ case 1968: /* 984K */+ sectors_per_track = 12; break;+ case 2132: /* 1066K */+ sectors_per_track = 13; break;+ case 2400: /* 1200K */+ case 2430: /* 1215K */+ case 2460: /* 1230K */+ case 2490: /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -