1 /* pcpart.c - manipulate fdisk partitions */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2009 Free Software Foundation, Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include <grub/types.h>
22 #include <grub/misc.h>
25 #include <grub/pc_partition.h>
26 #include <grub/device.h>
27 #include <grub/disk.h>
28 #include <grub/partition.h>
29 #include <grub/parttool.h>
31 static int activate_table_handle
= -1;
32 static int type_table_handle
= -1;
34 static struct grub_parttool_argdesc grub_pcpart_bootargs
[] =
36 {"boot", "Make partition active", GRUB_PARTTOOL_ARG_BOOL
},
40 static grub_err_t
grub_pcpart_boot (const grub_device_t dev
,
41 const struct grub_parttool_args
*args
)
44 grub_partition_t part
;
45 struct grub_pc_partition_mbr mbr
;
47 if (dev
->disk
->partition
->offset
)
48 return grub_error (GRUB_ERR_BAD_ARGUMENT
, "not a primary partition");
50 index
= ((struct grub_pc_partition
*) dev
->disk
->partition
->data
)->index
;
51 part
= dev
->disk
->partition
;
52 dev
->disk
->partition
= part
->parent
;
55 if (grub_disk_read (dev
->disk
, 0, 0, sizeof (mbr
), &mbr
))
57 dev
->disk
->partition
= part
;
61 if (args
[0].set
&& args
[0].bool)
63 for (i
= 0; i
< 4; i
++)
64 mbr
.entries
[i
].flag
= 0x0;
65 mbr
.entries
[index
].flag
= 0x80;
66 grub_printf ("Partition %d is active now. \n", index
);
70 mbr
.entries
[index
].flag
= 0x0;
71 grub_printf ("Cleared active flag on %d. \n", index
);
75 grub_disk_write (dev
->disk
, 0, 0, sizeof (mbr
), &mbr
);
77 dev
->disk
->partition
= part
;
82 static struct grub_parttool_argdesc grub_pcpart_typeargs
[] =
84 {"type", "Change partition type", GRUB_PARTTOOL_ARG_VAL
},
85 {"hidden", "Make partition hidden", GRUB_PARTTOOL_ARG_BOOL
},
89 static grub_err_t
grub_pcpart_type (const grub_device_t dev
,
90 const struct grub_parttool_args
*args
)
94 grub_partition_t part
;
95 struct grub_pc_partition_mbr mbr
;
97 index
= ((struct grub_pc_partition
*) dev
->disk
->partition
->data
)->index
;
98 part
= dev
->disk
->partition
;
99 dev
->disk
->partition
= part
->parent
;
101 /* Read the parttable. */
102 if (grub_disk_read (dev
->disk
, part
->offset
, 0,
105 dev
->disk
->partition
= part
;
110 type
= grub_strtoul (args
[0].str
, 0, 0);
112 type
= mbr
.entries
[index
].type
;
117 type
|= GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG
;
119 type
&= ~GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG
;
122 if (grub_pc_partition_is_empty (type
)
123 || grub_pc_partition_is_extended (type
))
125 dev
->disk
->partition
= part
;
126 return grub_error (GRUB_ERR_BAD_ARGUMENT
, "invalid type");
129 mbr
.entries
[index
].type
= type
;
130 grub_printf ("Setting partition type to 0x%x\n", type
);
132 /* Write the parttable. */
133 grub_disk_write (dev
->disk
, part
->offset
, 0,
136 dev
->disk
->partition
= part
;
138 return GRUB_ERR_NONE
;
141 GRUB_MOD_INIT (pcpart
)
143 activate_table_handle
= grub_parttool_register ("pc_partition_map",
145 grub_pcpart_bootargs
);
146 type_table_handle
= grub_parttool_register ("pc_partition_map",
148 grub_pcpart_typeargs
);
151 GRUB_MOD_FINI(pcpart
)
153 grub_parttool_unregister (activate_table_handle
);
154 grub_parttool_unregister (type_table_handle
);