[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] parttool
From: |
phcoder |
Subject: |
Re: [PATCH] parttool |
Date: |
Fri, 20 Mar 2009 20:33:25 +0100 |
User-agent: |
Thunderbird 2.0.0.21 (X11/20090318) |
Update
phcoder wrote:
Sorry I forgot include/grub/parttool.h
phcoder wrote:
Hello here is the implementation of parttool with the syntax I
proposed earlier and equivalent of parttype, makeactive and hide/unhide
--
Regards
Vladimir 'phcoder' Serbinenko
diff --git a/ChangeLog b/ChangeLog
index e3ac3ac..5fc3e37 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,20 @@
2009-03-15 Vladimir Serbinenko <address@hidden>
+
+ Parttool
+
+ * parttool/pcpart.c: new file
+ * commands/parttool.c: likewise
+ * conf/common.rmk: Added parttool.mod and pcpart.mod
+ * conf/i386-coreboot.rmk: added commands/parttool.c
+ and parttool/pcpart.c to grub-emu
+ * conf/i386-efi.rmk: likewise
+ * conf/i386-ieee1275.rmk: likewise
+ * conf/i386-pc.rmk: likewise
+ * conf/powerpc-ieee1275.rmk: likewise
+ * conf/sparc64-ieee1275.rmk: likewise
+ * conf/x86_64-ieee1275.rmk: likewise
+
+2009-03-15 Vladimir Serbinenko <address@hidden>
Efiemu
diff --git a/commands/parttool.c b/commands/parttool.c
new file mode 100644
index 0000000..fb6bdaa
--- /dev/null
+++ b/commands/parttool.c
@@ -0,0 +1,261 @@
+/* parttool.c - common dispatcher and parser for partition operations */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/dl.h>
+#include <grub/normal.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/partition.h>
+#include <grub/parttool.h>
+
+struct grub_parttool *parts = 0;
+static int curhandle = 0;
+static grub_dl_t mymod;
+
+int
+grub_parttool_register(const char *part_name,
+ const grub_parttool_function_t func,
+ const struct grub_parttool_argdesc *args)
+{
+ struct grub_parttool *cur;
+ int nargs = 0;
+ struct grub_parttool_argdesc *curarg;
+
+#ifndef GRUB_UTIL
+ if (!parts)
+ grub_dl_ref (mymod);
+#endif
+
+ cur = (struct grub_parttool *) grub_malloc (sizeof (struct grub_parttool));
+ cur->next = parts;
+ cur->name = grub_strdup (part_name);
+ cur->handle = curhandle++;
+ for (curarg = args; curarg->name != 0; curarg++)
+ nargs++;
+ cur->nargs = nargs;
+ cur->args = (struct grub_parttool_argdesc *)
+ grub_malloc ((nargs + 1) * sizeof (struct grub_parttool_argdesc));
+ grub_memcpy (cur->args, args,
+ (nargs + 1) * sizeof (struct grub_parttool_argdesc));
+
+ cur->func = func;
+ parts = cur;
+ return cur->handle;
+}
+
+void
+grub_parttool_unregister (int handle)
+{
+ struct grub_parttool *prev = 0, *cur, *t;
+ for (cur = parts; cur; )
+ if (cur->handle == handle)
+ {
+ grub_free (cur->args);
+ grub_free (cur->name);
+ if (prev)
+ prev->next = cur->next;
+ else
+ parts = cur->next;
+ t = cur;
+ cur = cur->next;
+ grub_free (t);
+ }
+ else
+ {
+ prev = cur;
+ cur = cur->next;
+ }
+#ifndef GRUB_UTIL
+ if (!parts)
+ grub_dl_unref (mymod);
+#endif
+}
+
+static grub_err_t
+grub_cmd_parttool (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc, char **args)
+{
+ grub_device_t dev;
+ struct grub_parttool *cur, *ptool;
+ int *parsed;
+ int i, j;
+ grub_err_t err = GRUB_ERR_NONE;
+
+ if (argc < 2)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "too few arguments");
+
+ if (args[0][0] == '(' && args[0][grub_strlen (args[0]) - 1] == ')')
+ {
+ args[0][grub_strlen (args[0])-1] = 0;
+ args[0]++;
+ }
+
+ dev = grub_device_open (args[0]);
+
+ if (!dev)
+ return grub_errno;
+
+ if (!dev->disk)
+ {
+ grub_device_close (dev);
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a disk");
+ }
+
+ if (!dev->disk->partition)
+ {
+ grub_device_close (dev);
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a partition");
+ }
+
+ parsed = (int *)grub_malloc (argc * sizeof (int));
+ grub_memset (parsed, 0, argc * sizeof (int));
+
+ for (i = 1; i < argc; i++)
+ if (!grub_strcmp (args[i], "help"))
+ {
+ int found = 0;
+ for (cur = parts; cur; cur = cur->next)
+ if (!grub_strcmp (dev->disk->partition->partmap->name, cur->name))
+ {
+ struct grub_parttool_argdesc *curarg;
+ found = 1;
+ for (curarg = cur->args; curarg->name; curarg++)
+ {
+ int spacing = 20;
+
+ spacing -= grub_strlen (curarg->name);
+ grub_printf ("%s", curarg->name);
+
+ switch (curarg->type)
+ {
+ case GRUB_PARTTOOL_ARG_BOOL:
+ grub_printf ("+/-");
+ spacing-=3;
+ break;
+
+ case GRUB_PARTTOOL_ARG_VAL:
+ grub_printf ("=VAL");
+ spacing-=4;
+ break;
+
+ case GRUB_PARTTOOL_ARG_END:
+ break;
+ }
+ while (spacing-- > 0)
+ grub_printf (" ");
+ grub_printf ("%s\n", curarg->desc);
+ }
+ }
+ if (!found)
+ grub_printf ("Sorry no parttool is available for %s\n",
+ dev->disk->partition->partmap->name);
+ return GRUB_ERR_NONE;
+ }
+
+ for (i = 1; i < argc; i++)
+ if (!parsed[i])
+ {
+ struct grub_parttool_argdesc *curarg;
+ struct grub_parttool_args *pargs;
+ for (cur = parts; cur; cur = cur->next)
+ if (!grub_strcmp (dev->disk->partition->partmap->name, cur->name))
+ {
+ for (curarg = cur->args; curarg->name; curarg++)
+ if (!grub_strncmp (curarg->name, args[i],
+ grub_strlen (curarg->name))
+ && ((curarg->type == GRUB_PARTTOOL_ARG_BOOL
+ && (args[i][grub_strlen (curarg->name)] == '+'
+ || args[i][grub_strlen (curarg->name)] == '-'))
+ || (curarg->type==GRUB_PARTTOOL_ARG_VAL
+ && args[i][grub_strlen (curarg->name)] == '=')))
+
+ break;
+ if (curarg->name)
+ break;
+ }
+ if (!cur)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "unrecognised argument %s",
+ args[i]);
+ ptool = cur;
+ pargs = (struct grub_parttool_args *)
+ grub_malloc (ptool->nargs * sizeof (struct grub_parttool_args));
+ grub_memset (pargs, 0,
+ ptool->nargs * sizeof (struct grub_parttool_args));
+ for (j = i; j < argc; j++)
+ if (!parsed[j])
+ {
+ for (curarg = ptool->args; curarg->name; curarg++)
+ if (!grub_strncmp (curarg->name, args[i],
+ grub_strlen (curarg->name))
+ && ((curarg->type == GRUB_PARTTOOL_ARG_BOOL
+ && (args[j][grub_strlen (curarg->name)] == '+'
+ || args[j][grub_strlen (curarg->name)] == '-'))
+ || (curarg->type == GRUB_PARTTOOL_ARG_VAL
+ && args[j][grub_strlen (curarg->name)] == '=')))
+ {
+ parsed[j] = 1;
+ pargs[curarg - ptool->args].set = 1;
+ switch (curarg->type)
+ {
+ case GRUB_PARTTOOL_ARG_BOOL:
+ pargs[curarg - ptool->args].bool
+ = (args[j][grub_strlen (curarg->name)] != '-');
+ break;
+
+ case GRUB_PARTTOOL_ARG_VAL:
+ pargs[curarg - ptool->args].str
+ = (args[j]+grub_strlen (curarg->name)+ 1);
+ break;
+
+ case GRUB_PARTTOOL_ARG_END:
+ break;
+ }
+ }
+ }
+
+ err = ptool->func (dev, pargs);
+ grub_free (pargs);
+ if (err)
+ break;
+ }
+
+ grub_device_close (dev);
+ return err;
+}
+
+GRUB_MOD_INIT(parttool)
+{
+ (void)mod; /* To stop warning. */
+ mymod = mod;
+ grub_register_command ("parttool", grub_cmd_parttool, GRUB_COMMAND_FLAG_BOTH,
+ "parttool PARTITION COMMANDS",
+ "perform COMMANDS on partition."
+ " use parttool PARTITION help for the list "
+ " of available commands", 0);
+}
+
+GRUB_MOD_FINI(parttool)
+{
+ grub_unregister_command ("parttool");
+}
diff --git a/conf/common.rmk b/conf/common.rmk
index 857d8b8..100fae7 100644
--- a/conf/common.rmk
+++ b/conf/common.rmk
@@ -334,7 +334,7 @@ pkglib_MODULES += hello.mod boot.mod handler.mod ls.mod
\
cmp.mod cat.mod help.mod search.mod
\
loopback.mod fs_uuid.mod configfile.mod echo.mod \
terminfo.mod test.mod blocklist.mod hexdump.mod \
- read.mod sleep.mod loadenv.mod crc.mod
+ read.mod sleep.mod loadenv.mod crc.mod parttool.mod pcpart.mod
# For hello.mod.
hello_mod_SOURCES = hello/hello.c
@@ -346,6 +346,16 @@ boot_mod_SOURCES = commands/boot.c
boot_mod_CFLAGS = $(COMMON_CFLAGS)
boot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+# For parttool.mod.
+parttool_mod_SOURCES = commands/parttool.c
+parttool_mod_CFLAGS = $(COMMON_CFLAGS)
+parttool_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
+# For pcpart.mod.
+pcpart_mod_SOURCES = parttool/pcpart.c
+pcpart_mod_CFLAGS = $(COMMON_CFLAGS)
+pcpart_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
# For handler.mod.
handler_mod_SOURCES = commands/handler.c
handler_mod_CFLAGS = $(COMMON_CFLAGS)
diff --git a/conf/i386-coreboot.rmk b/conf/i386-coreboot.rmk
index 33b798c..ddcc308 100644
--- a/conf/i386-coreboot.rmk
+++ b/conf/i386-coreboot.rmk
@@ -89,6 +89,7 @@ grub_emu_SOURCES = commands/boot.c commands/cat.c
commands/cmp.c \
\
disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \
disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \
+ commands/parttool.c parttool/pcpart.c \
grub_emu_init.c
grub_emu_LDFLAGS = $(LIBCURSES)
diff --git a/conf/i386-efi.rmk b/conf/i386-efi.rmk
index f9380d1..a2454d9 100644
--- a/conf/i386-efi.rmk
+++ b/conf/i386-efi.rmk
@@ -66,6 +66,7 @@ grub_emu_SOURCES = commands/boot.c commands/cat.c
commands/cmp.c \
\
disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \
disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \
+ commands/parttool.c parttool/pcpart.c \
grub_emu_init.c
grub_emu_LDFLAGS = $(LIBCURSES)
diff --git a/conf/i386-pc.rmk b/conf/i386-pc.rmk
index d5e1fab..3a00d17 100644
--- a/conf/i386-pc.rmk
+++ b/conf/i386-pc.rmk
@@ -152,6 +152,7 @@ grub_emu_SOURCES = commands/boot.c commands/cat.c
commands/cmp.c \
efiemu/modules/pnvram.c efiemu/i386/loadcore32.c \
efiemu/i386/loadcore64.c efiemu/symbols.c efiemu/prepare32.c \
efiemu/prepare64.c efiemu/uppermem.c lib/crc.c \
+ commands/parttool.c parttool/pcpart.c \
grub_emu_init.c
grub_emu_LDFLAGS = $(LIBCURSES)
diff --git a/conf/i386.rmk b/conf/i386.rmk
index 9ae65ae..4e86ed8 100644
--- a/conf/i386.rmk
+++ b/conf/i386.rmk
@@ -19,13 +19,3 @@ pkglib_MODULES += uppermem.mod
uppermem_mod_SOURCES = lib/i386/uppermem.c
uppermem_mod_CFLAGS = $(COMMON_CFLAGS)
uppermem_mod_LDFLAGS = $(COMMON_LDFLAGS)
-
-pkglib_MODULES += xnu.mod _xnu.mod
-_xnu_mod_SOURCES = loader/xnu_resume.c loader/i386/xnu.c loader/macho.c
loader/xnu.c loader/xnu_rescue.c loader/i386/xnu_helper.S
-_xnu_mod_CFLAGS = $(COMMON_CFLAGS) -Werror -Wall
-_xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
-_xnu_mod_ASFLAGS = $(COMMON_ASFLAGS)
-
-xnu_mod_SOURCES = loader/xnu_normal.c
-xnu_mod_CFLAGS = $(COMMON_CFLAGS) -Werror -Wall
-xnu_mod_LDFLAGS = $(COMMON_LDFLAGS)
diff --git a/conf/powerpc-ieee1275.rmk b/conf/powerpc-ieee1275.rmk
index f33d19a..66d1d58 100644
--- a/conf/powerpc-ieee1275.rmk
+++ b/conf/powerpc-ieee1275.rmk
@@ -70,6 +70,7 @@ grub_emu_SOURCES = commands/boot.c commands/cat.c
commands/cmp.c \
\
disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \
disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \
+ commands/parttool.c parttool/pcpart.c \
grub_script.tab.c grub_emu_init.c
grub_emu_LDFLAGS = $(LIBCURSES)
diff --git a/conf/sparc64-ieee1275.rmk b/conf/sparc64-ieee1275.rmk
index 75cc1f4..0794dc0 100644
--- a/conf/sparc64-ieee1275.rmk
+++ b/conf/sparc64-ieee1275.rmk
@@ -67,6 +67,7 @@ grub_mkimage_SOURCES = util/sparc64/ieee1275/grub-mkimage.c
util/misc.c \
# partmap/acorn.c \
# util/console.c util/grub-emu.c util/misc.c \
# util/hostdisk.c util/getroot.c \
+# commands/parttool.c parttool/pcpart.c \
# util/sparc64/ieee1275/misc.c
grub_emu_LDFLAGS = $(LIBCURSES)
diff --git a/conf/x86_64-efi.rmk b/conf/x86_64-efi.rmk
index ebbfb23..fb7bb32 100644
--- a/conf/x86_64-efi.rmk
+++ b/conf/x86_64-efi.rmk
@@ -68,6 +68,7 @@ grub_emu_SOURCES = commands/boot.c commands/cat.c
commands/cmp.c \
\
disk/raid.c disk/raid5_recover.c disk/raid6_recover.c \
disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c \
+ commands/parttool.c parttool/pcpart.c \
grub_emu_init.c
grub_emu_LDFLAGS = $(LIBCURSES)
diff --git a/include/grub/parttool.h b/include/grub/parttool.h
new file mode 100644
index 0000000..0e05f4c
--- /dev/null
+++ b/include/grub/parttool.h
@@ -0,0 +1,58 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_PARTTOOL_HEADER
+#define GRUB_PARTTOOL_HEADER 1
+
+struct grub_parttool_argdesc
+{
+ char *name;
+ char *desc;
+ enum {GRUB_PARTTOOL_ARG_END, GRUB_PARTTOOL_ARG_BOOL, GRUB_PARTTOOL_ARG_VAL}
+ type;
+};
+
+struct grub_parttool_args
+{
+ int set;
+ union
+ {
+ int bool;
+ char *str;
+ };
+};
+
+typedef grub_err_t (*grub_parttool_function_t) (const grub_device_t dev,
+ const struct grub_parttool_args
*args);
+
+struct grub_parttool
+{
+ struct grub_parttool *next;
+ char *name;
+ int handle;
+ int nargs;
+ struct grub_parttool_argdesc *args;
+ grub_parttool_function_t func;
+};
+
+int grub_parttool_register(const char *part_name,
+ const grub_parttool_function_t func,
+ const struct grub_parttool_argdesc *args);
+void grub_parttool_unregister (int handle);
+
+#endif /* ! GRUB_PARTTOOL_HEADER*/
diff --git a/parttool/pcpart.c b/parttool/pcpart.c
new file mode 100644
index 0000000..53e6403
--- /dev/null
+++ b/parttool/pcpart.c
@@ -0,0 +1,152 @@
+/* pcpart.c - manipulate fdisk partitions */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <grub/types.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/err.h>
+#include <grub/pc_partition.h>
+#include <grub/device.h>
+#include <grub/disk.h>
+#include <grub/partition.h>
+#include <grub/parttool.h>
+
+static int activate_table_handle = -1;
+static int type_table_handle = -1;
+
+static struct grub_parttool_argdesc grub_pcpart_bootargs[] =
+{
+ {"boot", "Make partition active", GRUB_PARTTOOL_ARG_BOOL},
+ {0, 0, 0}
+};
+
+static grub_err_t grub_pcpart_boot (const grub_device_t dev,
+ const struct grub_parttool_args *args)
+{
+ int i, index;
+ grub_partition_t part;
+ struct grub_pc_partition_mbr mbr;
+
+ if (dev->disk->partition->offset)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a primary partition");
+
+ index = dev->disk->partition->index;
+ part = dev->disk->partition;
+ dev->disk->partition = 0;
+
+ /* Read the MBR. */
+ if (grub_disk_read (dev->disk, 0, 0, sizeof (mbr), (char *) &mbr))
+ {
+ dev->disk->partition = part;
+ return grub_errno;
+ }
+
+ if (args[0].set && args[0].bool)
+ {
+ for (i = 0; i < 4; i++)
+ mbr.entries[i].flag = 0x0;
+ mbr.entries[index].flag = 0x80;
+ }
+ else
+ mbr.entries[index].flag = 0x0;
+
+ /* Write the MBR. */
+ grub_disk_write (dev->disk, 0, 0, sizeof (mbr), (char *) &mbr);
+
+ dev->disk->partition = part;
+
+ return GRUB_ERR_NONE;
+}
+
+static struct grub_parttool_argdesc grub_pcpart_typeargs[] =
+{
+ {"type", "Change partition type", GRUB_PARTTOOL_ARG_VAL},
+ {"hidden", "Make partition hidden", GRUB_PARTTOOL_ARG_BOOL},
+ {0, 0, 0}
+};
+
+static grub_err_t grub_pcpart_type (const grub_device_t dev,
+ const struct grub_parttool_args *args)
+{
+ int index;
+ grub_uint8_t type;
+ grub_partition_t part;
+ struct grub_pc_partition_mbr mbr;
+
+ index = dev->disk->partition->index;
+ part = dev->disk->partition;
+ dev->disk->partition = 0;
+
+ /* Read the parttable. */
+ if (grub_disk_read (dev->disk, part->offset, 0,
+ sizeof (mbr), (char *) &mbr))
+ {
+ dev->disk->partition = part;
+ return grub_errno;
+ }
+
+ if (args[0].set)
+ type = grub_strtoul (args[0].str, 0, 0);
+ else
+ type = mbr.entries[index].type;
+
+ if (args[1].set)
+ {
+ if (args[1].bool)
+ type |= GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG;
+ else
+ type &= ~GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG;
+ }
+
+ if (grub_pc_partition_is_empty (type)
+ || grub_pc_partition_is_extended (type))
+ {
+ dev->disk->partition = part;
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid type");
+ }
+
+ mbr.entries[index].type = type;
+
+ /* Write the parttable. */
+ grub_disk_write (dev->disk, part->offset, 0,
+ sizeof (mbr), (char *) &mbr);
+
+ dev->disk->partition = part;
+
+ return GRUB_ERR_NONE;
+}
+
+GRUB_MOD_INIT (pcpart)
+{
+ (void)mod; /* To stop warning. */
+
+ activate_table_handle = grub_parttool_register("pc_partition_map",
+ grub_pcpart_boot,
+ grub_pcpart_bootargs);
+ type_table_handle = grub_parttool_register("pc_partition_map",
+ grub_pcpart_type,
+ grub_pcpart_typeargs);
+
+}
+GRUB_MOD_FINI(pcpart)
+{
+ grub_parttool_unregister (activate_table_handle);
+ grub_parttool_unregister (type_table_handle);
+}