grub4dos icon indicating copy to clipboard operation
grub4dos copied to clipboard

Query about partnew and exFAT

Open steve6375 opened this issue 5 years ago • 10 comments

See https://github.com/a1ive/grub2-filemanager/issues/145 Does grub4dos add Partition Offset? Does it corrupt 0x1c-0x1f in VBR? Does it recalculate checksum in Sector 11 of VBR? Partition Offset at 0x40-0x47 in VBR and Sector 11 checksum should be updated.

steve6375 avatar Apr 01 '20 11:04 steve6375

exfat image file: image

image image

Bytes 0x1c-0x1f are overwritten (illegal) Bytes 0x40-0x47 not updated with new Partition offset (presumably checksum not updated in sector 11???)

steve6375 avatar Apr 01 '20 12:04 steve6375

Image file - sector 11 image After partnew image

Checksum sector not updated.

steve6375 avatar Apr 01 '20 12:04 steve6375

FAT32 BPB: struct grub_fat_bpb { grub_uint8_t jmp_boot[3]; grub_uint8_t oem_name[8]; grub_uint16_t bytes_per_sector; grub_uint8_t sectors_per_cluster; grub_uint16_t num_reserved_sectors; grub_uint8_t num_fats; grub_uint16_t num_root_entries; grub_uint16_t num_total_sectors_16; grub_uint8_t media; grub_uint16_t sectors_per_fat_16; grub_uint16_t sectors_per_track; grub_uint16_t num_heads; grub_uint32_t num_hidden_sectors; /* 0x1C */ grub_uint32_t num_total_sectors_32; ...

exFAT BPB: struct grub_exfat_bpb { grub_uint8_t jmp_boot[3]; grub_uint8_t oem_name[8]; grub_uint8_t mbz[53]; grub_uint64_t num_hidden_sectors; grub_uint64_t num_total_sectors; grub_uint32_t num_reserved_sectors; grub_uint32_t sectors_per_fat; grub_uint32_t cluster_offset; grub_uint32_t cluster_count; grub_uint32_t root_cluster; grub_uint32_t num_serial; grub_uint16_t fs_revision; grub_uint16_t volume_flags; grub_uint8_t bytes_per_sector_shift; grub_uint8_t sectors_per_cluster_shift; grub_uint8_t num_fats; grub_uint8_t num_ph_drive; grub_uint8_t reserved[8]; } GRUB_PACKED;

offset 好像是不一样的。

a1ive avatar Apr 01 '20 12:04 a1ive

image New partition is not recognised by Windows. I made (hd0,0) type 0 so only (hd0,1) is present.

Partition 1   SIZE=3826.988MiB   Type: 00   *ACTIVE*
START POS   = CYL:0 HD:32 SEC:33       END POS = CYL:487 HD:254 SEC:63
START (LBA) = 2,048 (00000800) SIZE (LBA) = 7,837,672 (007797E8) [End=7,839,719]

Partition 2   SIZE=297.081MiB   Type: 07 NTFS\exFAT       
START POS   = CYL:2 HD:55 SEC:48       END POS = CYL:77 HD:113 SEC:15
START (LBA) = 19,640 (00004CB8) SIZE (LBA) = 608,422 (000948A6) [End=628,061]

steve6375 avatar Apr 01 '20 12:04 steve6375

https://github.com/a1ive/grub/blob/0debea8e30bfc4e496fc6aab8dc9ed359f745daa/grub-core/lib/fatfs/ff.c#L6094

		/* Create two set of the exFAT VBR blocks */
		sect = b_vol;
		for (n = 0; n < 2; n++) {
			/* Main record (+0) */
			mem_set(buf, 0, ss);
			mem_cpy(buf + BS_JmpBoot, "\xEB\x76\x90" "EXFAT   ", 11);	/* Boot jump code (x86), OEM name */
			st_qword(buf + BPB_VolOfsEx, b_vol);					/* Volume offset in the physical drive [sector] */
			st_qword(buf + BPB_TotSecEx, sz_vol);					/* Volume size [sector] */
			st_dword(buf + BPB_FatOfsEx, (DWORD)(b_fat - b_vol));	/* FAT offset [sector] */
			st_dword(buf + BPB_FatSzEx, sz_fat);					/* FAT size [sector] */
			st_dword(buf + BPB_DataOfsEx, (DWORD)(b_data - b_vol));	/* Data offset [sector] */
			st_dword(buf + BPB_NumClusEx, n_clst);					/* Number of clusters */
			st_dword(buf + BPB_RootClusEx, 2 + tbl[0] + tbl[1]);	/* Root dir cluster # */
			st_dword(buf + BPB_VolIDEx, GET_FATTIME());				/* VSN */
			st_word(buf + BPB_FSVerEx, 0x100);						/* Filesystem version (1.00) */
			for (buf[BPB_BytsPerSecEx] = 0, i = ss; i >>= 1; buf[BPB_BytsPerSecEx]++) ;	/* Log2 of sector size [byte] */
			for (buf[BPB_SecPerClusEx] = 0, i = sz_au; i >>= 1; buf[BPB_SecPerClusEx]++) ;	/* Log2 of cluster size [sector] */
			buf[BPB_NumFATsEx] = 1;					/* Number of FATs */
			buf[BPB_DrvNumEx] = 0x80;				/* Drive number (for int13) */
			st_word(buf + BS_BootCodeEx, 0xFEEB);	/* Boot code (x86) */
			st_word(buf + BS_55AA, 0xAA55);			/* Signature (placed here regardless of sector size) */
			for (i = sum = 0; i < ss; i++) {		/* VBR checksum */
				if (i != BPB_VolFlagEx && i != BPB_VolFlagEx + 1 && i != BPB_PercInUseEx) sum = xsum32(buf[i], sum);
			}
			if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
			/* Extended bootstrap record (+1..+8) */
			mem_set(buf, 0, ss);
			st_word(buf + ss - 2, 0xAA55);	/* Signature (placed at end of sector) */
			for (j = 1; j < 9; j++) {
				for (i = 0; i < ss; sum = xsum32(buf[i++], sum)) ;	/* VBR checksum */
				if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
			}
			/* OEM/Reserved record (+9..+10) */
			mem_set(buf, 0, ss);
			for ( ; j < 11; j++) {
				for (i = 0; i < ss; sum = xsum32(buf[i++], sum)) ;	/* VBR checksum */
				if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
			}
			/* Sum record (+11) */
			for (i = 0; i < ss; i += 4) st_dword(buf + i, sum);		/* Fill with checksum value */
			if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
		}
static DWORD xsum32 (	/* Returns 32-bit checksum */
	BYTE  dat,			/* Byte to be calculated (byte-by-byte processing) */
	DWORD sum			/* Previous sum value */
)
{
	sum = ((sum & 1) ? 0x80000000 : 0) + (sum >> 1) + dat;
	return sum;
}

a1ive avatar Apr 01 '20 12:04 a1ive

EXFAT300A.zip Here is partition image of exFAT 300MB that can be used to test with partnew re. exFAT xsum - locations at 106 107 112 should not be checksummed because they are changed by filesystem.

UINT32 VBRChecksum(const unsigned char octets[], long NumberOfBytes)
{
 UINT32 Checksum = 0;
 long Index;

 for (Index = 0; Index < NumberOfBytes; Index++)
 {
 if (Index == 106 || Index == 107 || Index == 112)
 {
 continue;
 }
 Checksum = ((Checksum <<31) | (Checksum>> 1)) + (UINT32) octets[Index];
 }
 return Checksum;
Figure 19 Code snippet 

steve6375 avatar Apr 01 '20 12:04 steve6375

If VBR bytes 0x1c-0x1f >> 00 after partnew - then Windows can read exFAT partition image

  • CANNOT ACCESS
  • now repair bytes image image

steve6375 avatar Apr 01 '20 13:04 steve6375

If change 0x40 then get Bad volume image image

steve6375 avatar Apr 01 '20 14:04 steve6375

The partnew function is not applicable to the exFAT file system . In other words, partnew failed to consider the exFAT file system. After all, the exFAT file system is post - developed .

yaya2007 avatar Apr 03 '20 07:04 yaya2007

OK - simplest fix is to remove the hidden sectors update to VBR for exFAT. Then, at least, the exFAT partition will be accessible to Windows (but not bootable).

steve6375 avatar Apr 03 '20 08:04 steve6375