On Wed, 26 Jul 2000, Stefan Ondrejicka wrote:

Hello,

> > > So, can you rename my partid to parttype and add it to grub ? I think I
> > > saw such something in grub TODO list.
> > 
> >   Send a cleaned patch. My time is very limited currently.

Ok. I have just cleaned that patch - it uses now set_device() and
safe_parse_maxint() to parse parametrs string. I leaved the name partid.
I have also adjusted the implementation to allow change type of
unallocated and extended partitions.

Also I have implemented new command "partnew" . It is implementation of
your proposed idea to replace my rules breaking command "partmap". It
creates newprimary  partition with specified type , start sector and
length. the syntax is

partnew partiton type start length

for example:

partnew (hd0,2) 0xa9 121098 500000

it creates new primary partition in third partion entry with type 0xa9 at
sector 121098 with size 500000 sectors.

I hope this patch will be acceptable for you.

Best regards,
Stevo.

-- 
Stefan Ondrejicka <[EMAIL PROTECTED]>
Beethovenova 11, 917 08 Trnava, Slovakia
http://www.idata.sk/~ondrej/
diff -ruN grub-0.5.95/stage2/builtins.c grub/stage2/builtins.c
--- grub-0.5.95/stage2/builtins.c       Thu Jun  1 08:26:52 2000
+++ grub/stage2/builtins.c      Tue Aug 15 22:19:46 2000
@@ -3063,6 +3063,41 @@
 };
 
 
+/* partid */
+static int
+partid_func (char *arg, int flags)
+{
+  return set_partition_type(arg);
+}
+
+static struct builtin builtin_partid =
+{
+   "partid",
+   partid_func,
+   BUILTIN_CMDLINE | BUILTIN_MENU,
+   "partid PARTITION ID",
+   "Change PARTITION type to ID."
+};
+
+
+/* partnew */
+static int
+partnew_func (char *arg, int flags)
+{
+  return partnew(arg);
+}
+
+static struct builtin builtin_partnew =
+{
+   "partnew",
+   partnew_func,
+   BUILTIN_CMDLINE | BUILTIN_MENU,
+   "partnew PARTITION ID START LENGTH",
+   "Create new primary partition entry with type ID, "
+   "starting at sector START with LENGHT sectors."
+};
+
+
 /* The table of builtin commands. Sorted in dictionary order.  */
 struct builtin *builtin_table[] =
 {
@@ -3096,6 +3131,8 @@
   &builtin_map,
   &builtin_module,
   &builtin_modulenounzip,
+  &builtin_partid,
+  &builtin_partnew,
   &builtin_password,
   &builtin_pause,
   &builtin_quit,
diff -ruN grub-0.5.95/stage2/disk_io.c grub/stage2/disk_io.c
--- grub-0.5.95/stage2/disk_io.c        Wed Apr 19 22:34:28 2000
+++ grub/stage2/disk_io.c       Tue Aug 15 22:21:50 2000
@@ -1520,3 +1520,248 @@
   if (fsys_table[fsys_type].close_func != 0)
     (*(fsys_table[fsys_type].close_func)) ();
 }
+
+
+static int
+real_set_partition_type(unsigned int drive, unsigned int id, unsigned int ssec, 
+unsigned int off, int *l_num, int type)
+{
+  int i;
+  int rv = -1;
+  char *l_block = (char *) SCRATCHADDR;
+  int wasl = 1;
+
+  for(i = 0 ; i < PC_SLICE_MAX ; i++)
+  {
+    if (wasl)
+    {
+      /* Read the logical partition block. */
+      if (!rawread(drive, ssec + off, 0, SECTOR_SIZE, (char *) SCRATCHADDR))
+        return -1;
+      l_block = (char *) SCRATCHADDR;
+
+      if (!PC_MBR_CHECK_SIG(l_block))
+      {
+        errnum = ERR_BAD_PART_TABLE;
+        return -1;
+      }
+      wasl = 0;
+    }
+
+    /* here we are changing type of partions from primary partiton table
+      to allow type changes also on unmapped & extended partitions
+      ssec is zero for all primary partitions */
+    if (!ssec && i == id)
+    {
+      PC_SLICE_TYPE(l_block, i) = type;
+
+      /* Write back.  */
+      buf_track = -1;
+      if (biosdisk (BIOSDISK_WRITE, drive, &buf_geom, ssec+off, 1, SCRATCHSEG))
+      {
+        errnum = ERR_WRITE;
+        return -1;
+      }
+      return 0;
+    }
+
+    if (PC_SLICE_TYPE(l_block, i) == PC_SLICE_TYPE_NONE)
+      continue;
+
+    if (IS_PC_SLICE_TYPE_EXTENDED(PC_SLICE_TYPE(l_block, i)))
+    {
+      wasl = 1;
+      rv = real_set_partition_type(drive, id, ssec ? ssec : PC_SLICE_START(l_block, 
+i), ssec ? PC_SLICE_START(l_block, i) : 0, l_num, type);
+      if (rv == 0)
+       break;
+    }
+    else
+    {
+      /* here we are chaging only ID of logical patitions in extended partion
+         ssec is nonzero for all logical partitons */
+      if (ssec && (*l_num == id))
+      {
+        PC_SLICE_TYPE(l_block, i) = type;
+
+        /* Write back.  */
+        buf_track = -1;
+        if (biosdisk (BIOSDISK_WRITE, drive, &buf_geom, ssec+off, 1, SCRATCHSEG))
+        {
+          errnum = ERR_WRITE;
+          return -1;
+        }
+        return 0;
+      }
+      if (ssec)
+        (*l_num)++;
+    }
+  }
+
+  return rv;
+}
+
+int
+set_partition_type (char *arg)
+{
+  int drive;
+  int part;
+  int id;
+  int l_num = 4;
+  char *p;
+
+  if (!(p = set_device(arg)))
+  {
+    current_drive = 0xFF;
+    return -1;
+  }
+  drive = current_drive;
+  part = (current_partition & 0xFF0000) >> 16;
+
+  while(*p == ' ') p++;
+  if (!safe_parse_maxint(&p, &id) || id > 0xFF)
+  {
+    return -1;
+  }
+
+  /* check if drive is present and get its geometry */
+  if (buf_drive != drive)
+  {
+    if (get_diskinfo(drive, &buf_geom))
+    {
+      errnum = ERR_NO_DISK;
+      return -1;
+    }
+    buf_drive = drive;
+    buf_track = -1;
+  }
+
+  return real_set_partition_type(drive, part, 0, 0, &l_num, id);
+} 
+
+static void
+sec_nr_to_chs(unsigned long sector, struct geometry *geom, unsigned long *c, unsigned 
+long *h, unsigned long *s)
+{
+  unsigned long tc,th,ts;
+
+  tc = sector / (geom->heads * geom->sectors);
+  th = (sector / geom->sectors) % geom->heads;
+  ts = sector % geom->sectors;
+
+  if (tc > 1023)
+  {
+     tc = 1023;
+     th = geom->heads - 1;
+     ts = geom->sectors - 1;
+   }
+
+   *c = tc % 0x100;
+   *h = th;
+   *s = ts + 1 + (tc >> 8 << 6);
+}
+
+static int
+create_new_partition(int drive, int part, int id, unsigned long start, unsigned long 
+length)
+{
+  char *mbr_block;
+  unsigned long sc, sh, ss, ec, eh, es;
+
+  /* Read the MBR block.  */
+  if (!rawread(drive, 0, 0, SECTOR_SIZE, (char *) SCRATCHADDR))
+    return -1;
+
+  mbr_block = (char *) SCRATCHADDR;
+  if (!PC_MBR_CHECK_SIG(mbr_block))
+  {
+    errnum = ERR_BAD_PART_TABLE;
+    return -1;
+  }
+
+  sec_nr_to_chs(start, &buf_geom, &sc, &sh, &ss);
+  sec_nr_to_chs(start + length - 1, &buf_geom, &ec, &eh, &es);
+
+#ifdef DEBUG
+  grub_printf("Geometry - %d %d %d\n", buf_geom.cylinders, buf_geom.heads, 
+buf_geom.sectors);
+  grub_printf("Start - %d %d %d %d\n", start, sc, sh, ss);
+  grub_printf("End - %d %d %d %d\n", start + length - 1, ec, eh, es);
+#endif
+
+  PC_SLICE_FLAG(mbr_block, part) = 0x0;
+  PC_SLICE_HEAD(mbr_block, part) = sh;
+  PC_SLICE_SEC(mbr_block, part) = ss;
+  PC_SLICE_CYL(mbr_block, part) = sc;
+  PC_SLICE_TYPE(mbr_block, part) = id;
+  PC_SLICE_EHEAD(mbr_block, part) = eh;
+  PC_SLICE_ESEC(mbr_block, part) = es;
+  PC_SLICE_ECYL(mbr_block, part) = ec;
+  PC_SLICE_START(mbr_block, part) = start;
+  PC_SLICE_LENGTH(mbr_block, part) = length;
+
+  /* write MBR back */
+  buf_track = -1;
+  if (biosdisk (BIOSDISK_WRITE, drive, &buf_geom, 0, 1, SCRATCHSEG))
+  {
+    errnum = ERR_WRITE;
+    return -1;
+  }
+ 
+  return 0;
+}
+
+int
+partnew(char *arg)
+{
+  int drive;
+  int part;
+  int id;
+  unsigned int start,length;
+  char *p;
+
+  /* first parse arg */
+  /* format (drive,part) id start_sector length */
+  if (!(p = set_device(arg)))
+  {
+    current_drive = 0xFF;
+    return -1;
+  }
+  drive = current_drive;
+  part = (current_partition & 0xFF0000) >> 16;
+
+  if (part > 3)
+  {
+    grub_printf("We are able to create only primary partitions.\n");
+    errnum = ERR_BAD_ARGUMENT;
+    return -1;
+  }
+
+  while(*p == ' ') p++;
+  if (!safe_parse_maxint(&p, &id))
+  {
+    return -1;
+  }
+
+  while(*p == ' ') p++;
+  if (!safe_parse_maxint(&p, &start))
+  {
+    return -1;
+  }
+
+  while(*p == ' ') p++;
+  if (!safe_parse_maxint(&p, &length))
+  {
+    return -1;
+  }
+
+  /* check if drive is present and get its geometry */
+  if (buf_drive != drive)
+  {
+    if (get_diskinfo(drive, &buf_geom))
+    {
+      errnum = ERR_NO_DISK;
+      return -1;
+    }
+    buf_drive = drive;
+    buf_track = -1;
+  }
+
+  return create_new_partition(drive, part, id, start, length);
+}
+
diff -ruN grub-0.5.95/stage2/shared.h grub/stage2/shared.h
--- grub-0.5.95/stage2/shared.h Tue May 30 17:58:09 2000
+++ grub/stage2/shared.h        Tue Aug 15 22:23:21 2000
@@ -768,6 +768,16 @@
 /* Close a file.  */
 void grub_close (void);
 
+/* Set partition type
+   arg is parameter string in format PARTITION TYPE */
+int set_partition_type(char *arg);
+
+/* Create new partition at specified offset and
+   with specified length and partition type     
+   arg is parameter string in format PARTITION TYPE START LENGTH */
+int partnew(char *arg);
+
+
 /* List the contents of the directory that was opened with GRUB_OPEN,
    printing all completions. */
 int dir (char *dirname);

Reply via email to