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);