bug-grub
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: "partnew" Command Writes Wrong Ending Cylinder in MPT


From: adrian15
Subject: Re: "partnew" Command Writes Wrong Ending Cylinder in MPT
Date: Sun, 19 Nov 2006 20:56:49 +0100
User-agent: Mozilla Thunderbird 1.0.7 (Windows/20050923)

sburtchin escribió:

sburtchin wrote:
partnew 0x05 2071440 10508400

I tried with (hd1,0) and with different filesystem types but the result is
always same: "830" instead of "831" is written to the ending cylinder
field {(hd1) has CHS 833/240/63.}

I've done some additional testing.  Here are a few more unexpected results:
For example: "partnew (hd0,0) 0x0F 2056320 158019120" writes "1021" for end
cylinder
For example: "partnew (hd0,2) 0x0C 116575200 36136800" writes "1021" for
begin & end cylinder
For example: "partnew (hd0,3) 0x00 0 0" writes C/H/S 0/0/1 thru 1021/164/4
For example: "partnew (hd1,2) 0x00 0 0" writes C/H/S 0/0/1 thru 830/164/4
{(hd0) has CHS 10587/240/63.}

Just a hunch, but it seems that partnew cannot write a begin or end cylinder
larger than the largest allowed for that drive minus 2.

I don't know if it matters in actual practice, but "partnew (hd0,3) 0x00 0
0" should write C/H/S 0/0/0 thru 0/0/0.

Hi Sburtchin.

I have been looking at the partnew code and I am not very sure what it
does :) .
What is the algorigthm that partnew should do in your opinnion.

I mean given a partition type, its start and its length how do you
calculate the ending cylinder field ?

I am going to explain more or less how I understand that the end
cylinder is calculated.

new_start + new_len - 1, &end_cl, &end_ch, &end_dh

lba_to_chs function modifies end_cl thanks to:
bbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahhhhhhhhhhhhhhhhhhhhhh

I am tired. Here is the important source code:

partnew_func (char *arg, int flags)
{
  int new_type, new_start, new_len;
  int start_cl, start_ch, start_dh;
  int end_cl, end_ch, end_dh;
  int entry;
  char mbr[512];

  /* Convert a LBA address to a CHS address in the INT 13 format.  */
  auto void lba_to_chs (int lba, int *cl, int *ch, int *dh);
  void lba_to_chs (int lba, int *cl, int *ch, int *dh)
    {
      int cylinder, head, sector;

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

      if (cylinder >= buf_geom.cylinders)
        cylinder = buf_geom.cylinders - 1;

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

  /* Get the drive and the partition.  */
  if (! set_device (arg))
    return 1;

  /* The drive must be a hard disk.  */
  if (! (current_drive & 0x80))
    {
      errnum = ERR_BAD_ARGUMENT;
      return 1;
    }

  /* The partition must a primary partition.  */
  if ((current_partition >> 16) > 3
      || (current_partition & 0xFFFF) != 0xFFFF)
    {
      errnum = ERR_BAD_ARGUMENT;
      return 1;
    }

  entry = current_partition >> 16;

  /* Get the new partition type.  */
  arg = skip_to (0, arg);
  if (! safe_parse_maxint (&arg, &new_type))
    return 1;

  /* The partition type is unsigned char.  */
  if (new_type > 0xFF)
    {
      errnum = ERR_BAD_ARGUMENT;
      return 1;
    }

  /* Get the new partition start.  */
  arg = skip_to (0, arg);
  if (! safe_parse_maxint (&arg, &new_start))
    return 1;

  /* Get the new partition length.  */
  arg = skip_to (0, arg);
  if (! safe_parse_maxint (&arg, &new_len))
    return 1;

  /* Read the MBR.  */
  if (! rawread (current_drive, 0, 0, SECTOR_SIZE, mbr))
    return 1;

  /* Check if the new partition will fit in the disk.  */
  if (new_start + new_len > buf_geom.total_sectors)
    {
      errnum = ERR_GEOM;
      return 1;
    }

  /* Store the partition information in the MBR.  */
  lba_to_chs (new_start, &start_cl, &start_ch, &start_dh);
  lba_to_chs (new_start + new_len - 1, &end_cl, &end_ch, &end_dh);

Maybe you may find the error better than me as long as you have more
knowledge than me on how this C/H/S stuff should work.

Maybe is it only a matter of switching on / off the lba addressing on
the bios ? I do not know.

adrian15






reply via email to

[Prev in Thread] Current Thread [Next in Thread]