Skip to content
This repository has been archived by the owner on Jun 28, 2023. It is now read-only.

Commit

Permalink
msdos: add lba_to_chs
Browse files Browse the repository at this point in the history
  • Loading branch information
a1ive committed Dec 13, 2019
1 parent 4b9b541 commit a645fed
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 54 deletions.
27 changes: 0 additions & 27 deletions grub-core/commands/gptsync.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,33 +31,6 @@

GRUB_MOD_LICENSE ("GPLv3+");

/* Convert a LBA address to a CHS address in the INT 13 format. */
/* Taken from grub1. */
/* XXX: use hardcoded geometry of C = 1024, H = 255, S = 63.
Is it a problem?
*/
static void
lba_to_chs (grub_uint32_t lba, grub_uint8_t *cl, grub_uint8_t *ch,
grub_uint8_t *dh)
{
grub_uint32_t cylinder, head, sector;
grub_uint32_t sectors = 63, heads = 255, cylinders = 1024;

sector = lba % sectors + 1;
head = (lba / sectors) % heads;
cylinder = lba / (sectors * heads);

if (cylinder >= cylinders)
{
*cl = *ch = *dh = 0xff;
return;
}

*cl = sector | ((cylinder & 0x300) >> 2);
*ch = cylinder & 0xFF;
*dh = head;
}

static grub_err_t
grub_cmd_gptsync (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
Expand Down
27 changes: 0 additions & 27 deletions grub-core/commands/partnew.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,33 +60,6 @@ enum options_partnew
PARTNEW_LENGTH,
};

/* Convert a LBA address to a CHS address in the INT 13 format. */
/* Taken from grub1. */
/* XXX: use hardcoded geometry of C = 1024, H = 255, S = 63.
Is it a problem?
*/
static void
lba_to_chs (grub_uint32_t lba, grub_uint8_t *cl, grub_uint8_t *ch,
grub_uint8_t *dh)
{
grub_uint32_t cylinder, head, sector;
grub_uint32_t sectors = 63, heads = 255, cylinders = 1024;

sector = lba % sectors + 1;
head = (lba / sectors) % heads;
cylinder = lba / (sectors * heads);

if (cylinder >= cylinders)
{
*cl = *ch = *dh = 0xff;
return;
}

*cl = sector | ((cylinder & 0x300) >> 2);
*ch = cylinder & 0xFF;
*dh = head;
}

struct block_ctx
{
grub_disk_addr_t start;
Expand Down
27 changes: 27 additions & 0 deletions include/grub/msdos_partition.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,4 +140,31 @@ grub_partition_msdos_iterate (grub_disk_t disk,
grub_partition_iterate_hook_t hook,
void *hook_data);

/* Convert a LBA address to a CHS address in the INT 13 format. */
/* Taken from grub1. */
/* XXX: use hardcoded geometry of C = 1024, H = 255, S = 63.
Is it a problem?
*/
static inline void
lba_to_chs (grub_uint32_t lba, grub_uint8_t *cl, grub_uint8_t *ch,
grub_uint8_t *dh)
{
grub_uint32_t cylinder, head, sector;
grub_uint32_t sectors = 63, heads = 255, cylinders = 1024;

sector = lba % sectors + 1;
head = (lba / sectors) % heads;
cylinder = lba / (sectors * heads);

if (cylinder >= cylinders)
{
*cl = *ch = *dh = 0xff;
return;
}

*cl = sector | ((cylinder & 0x300) >> 2);
*ch = cylinder & 0xFF;
*dh = head;
}

#endif /* ! GRUB_PC_PARTITION_HEADER */

8 comments on commit a645fed

@a1ive
Copy link
Owner Author

@a1ive a1ive commented on a645fed Jan 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#26

@steve6375
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*cl = *ch = *dh = 0xff;

This is still incorrect. should be FE FF FF not FF FF FF.
Cannot be read by grub4dos.

@steve6375
Copy link

@steve6375 steve6375 commented on a645fed Jan 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think dh = 0xfe
http://starman.vertcomp.com/asm/mbr/PartTables.htm

NOTE:For partitions which begin or end beyond  the 1024th cylinder, the three CHS bytes should always be filled with: FE FF FF ; which are decoded as follows:Byte 1:  FEh = 254  for a total of 255 heads.Bytes 2 and 3:  FFh and FFh — split into two full binary counts of 6 bits (11 1111; 3Fh = 63 sectors), and 10 bits (11 1111 1111) or 3FFh = 1023 for a total of 1024 cylinders. CHS: 1023, 254, 63.This tuple corresponds to an LBA sector of: 16450559. That's a point where about  8.4 GB of hard disk sectors could be accessed (16,450,560 sectors * 512 bytes/sector = 8,422,686,720 bytes).16-byte partition table entries can not exceed 1024 cylinders for their Starting and Ending CHS bytes!  When utility programs display CHS tuples with a cylinder value larger than 1023, they can only do so by computing pseudo-CHS values from the 4-byte "Starting Sector" or "Partition Size" values.

@steve6375
Copy link

@steve6375 steve6375 commented on a645fed Jan 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK now :-) it is FE FF FF and grub4dos can see the partition now. 👍

@a1ive
Copy link
Owner Author

@a1ive a1ive commented on a645fed Jan 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GNU GRUB also has this bug (http://git.savannah.gnu.org/cgit/grub.git/tree/grub-core/commands/gptsync.c#n52)
Maybe we should report it.

@steve6375
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you report it? When would it be used as it has no partnew? when would it make a partition table entry?

@a1ive
Copy link
Owner Author

@a1ive a1ive commented on a645fed Jan 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's in gptsync, a module to edit hybrid mbr in gpt disk.
I don't know how to use mailing list to upload patch.

@steve6375
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.