]> git.proxmox.com Git - grub2.git/blob - util/grub-setup.c
Add --no-rs-codes flag to optionally disable reed-solomon codes in grub-install and...
[grub2.git] / util / grub-setup.c
1 /* grub-setup.c - make GRUB usable */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011 Free Software Foundation, Inc.
5 *
6 * GRUB 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 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GRUB 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.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <config.h>
21
22 #define _GNU_SOURCE 1
23
24 #include <string.h>
25
26 #include <grub/types.h>
27 #include <grub/emu/misc.h>
28 #include <grub/util/misc.h>
29 #include <grub/device.h>
30 #include <grub/disk.h>
31 #include <grub/file.h>
32 #include <grub/fs.h>
33 #include <grub/partition.h>
34 #include <grub/env.h>
35 #include <grub/emu/hostdisk.h>
36 #include <grub/term.h>
37 #include <grub/i18n.h>
38 #include <grub/crypto.h>
39 #include <grub/emu/getroot.h>
40 #include <grub/util/install.h>
41
42 #include <argp.h>
43
44 /* On SPARC this program fills in various fields inside of the 'boot' and 'core'
45 * image files.
46 *
47 * The 'boot' image needs to know the OBP path name of the root
48 * device. It also needs to know the initial block number of
49 * 'core' (which is 'diskboot' concatenated with 'kernel' and
50 * all the modules, this is created by grub-mkimage). This resulting
51 * 'boot' image is 512 bytes in size and is placed in the second block
52 * of a partition.
53 *
54 * The initial 'diskboot' block acts as a loader for the actual GRUB
55 * kernel. It contains the loading code and then a block list.
56 *
57 * The block list of 'core' starts at the end of the 'diskboot' image
58 * and works it's way backwards towards the end of the code of 'diskboot'.
59 *
60 * We patch up the images with the necessary values and write out the
61 * result.
62 */
63
64 #define DEFAULT_BOOT_FILE "boot.img"
65 #define DEFAULT_CORE_FILE "core.img"
66
67 /* Non-printable "keys" for arguments with no short form.
68 * See grub-core/gnulib/argp.h for details. */
69 enum {
70 NO_RS_CODES_KEY = 0x100,
71 };
72
73 static struct argp_option options[] = {
74 {"boot-image", 'b', N_("FILE"), 0,
75 N_("use FILE as the boot image [default=%s]"), 0},
76 {"core-image", 'c', N_("FILE"), 0,
77 N_("use FILE as the core image [default=%s]"), 0},
78 {"directory", 'd', N_("DIR"), 0,
79 N_("use GRUB files in the directory DIR [default=%s]"), 0},
80 {"device-map", 'm', N_("FILE"), 0,
81 N_("use FILE as the device map [default=%s]"), 0},
82 {"force", 'f', 0, 0,
83 N_("install even if problems are detected"), 0},
84 {"skip-fs-probe",'s',0, 0,
85 N_("do not probe for filesystems in DEVICE"), 0},
86 {"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
87 {"allow-floppy", 'a', 0, 0,
88 /* TRANSLATORS: The potential breakage isn't limited to floppies but it's
89 likely to make the install unbootable from HDD. */
90 N_("make the drive also bootable as floppy (default for fdX devices). May break on some BIOSes."), 0},
91 {"no-rs-codes", NO_RS_CODES_KEY, 0, 0,
92 N_("Do not apply any reed-solomon codes when embedding core.img. "
93 "This option is only available on x86 BIOS targets."), 0},
94 { 0, 0, 0, 0, 0, 0 }
95 };
96
97 static char *
98 help_filter (int key, const char *text, void *input __attribute__ ((unused)))
99 {
100 switch (key)
101 {
102 case 'b':
103 return xasprintf (text, DEFAULT_BOOT_FILE);
104
105 case 'c':
106 return xasprintf (text, DEFAULT_CORE_FILE);
107
108 case 'd':
109 return xasprintf (text, DEFAULT_DIRECTORY);
110
111 case 'm':
112 return xasprintf (text, DEFAULT_DEVICE_MAP);
113
114 default:
115 return (char *) text;
116 }
117 }
118
119 struct arguments
120 {
121 char *boot_file;
122 char *core_file;
123 char *dir;
124 char *dev_map;
125 int force;
126 int fs_probe;
127 int allow_floppy;
128 char *device;
129 int add_rs_codes;
130 };
131
132 static error_t
133 argp_parser (int key, char *arg, struct argp_state *state)
134 {
135 /* Get the input argument from argp_parse, which we
136 know is a pointer to our arguments structure. */
137 struct arguments *arguments = state->input;
138
139 switch (key)
140 {
141 case 'a':
142 arguments->allow_floppy = 1;
143 break;
144
145 case 'b':
146 if (arguments->boot_file)
147 free (arguments->boot_file);
148
149 arguments->boot_file = xstrdup (arg);
150 break;
151
152 case 'c':
153 if (arguments->core_file)
154 free (arguments->core_file);
155
156 arguments->core_file = xstrdup (arg);
157 break;
158
159 case 'd':
160 if (arguments->dir)
161 free (arguments->dir);
162
163 arguments->dir = xstrdup (arg);
164 break;
165
166 case 'm':
167 if (arguments->dev_map)
168 free (arguments->dev_map);
169
170 arguments->dev_map = xstrdup (arg);
171 break;
172
173 case 'f':
174 arguments->force = 1;
175 break;
176
177 case 's':
178 arguments->fs_probe = 0;
179 break;
180
181 case 'v':
182 verbosity++;
183 break;
184
185 case NO_RS_CODES_KEY:
186 arguments->add_rs_codes = 0;
187 break;
188
189 case ARGP_KEY_ARG:
190 if (state->arg_num == 0)
191 arguments->device = xstrdup(arg);
192 else
193 {
194 /* Too many arguments. */
195 fprintf (stderr, _("Unknown extra argument `%s'."), arg);
196 fprintf (stderr, "\n");
197 argp_usage (state);
198 }
199 break;
200
201 case ARGP_KEY_NO_ARGS:
202 fprintf (stderr, "%s", _("No device is specified.\n"));
203 argp_usage (state);
204 exit (1);
205 break;
206
207 default:
208 return ARGP_ERR_UNKNOWN;
209 }
210
211 return 0;
212 }
213
214 static struct argp argp = {
215 options, argp_parser, N_("DEVICE"),
216 "\n"N_("\
217 Set up images to boot from DEVICE.\n\
218 \n\
219 You should not normally run this program directly. Use grub-install instead.")
220 "\v"N_("\
221 DEVICE must be an OS device (e.g. /dev/sda)."),
222 NULL, help_filter, NULL
223 };
224
225 static char *
226 get_device_name (char *dev)
227 {
228 size_t len = strlen (dev);
229
230 if (dev[0] != '(' || dev[len - 1] != ')')
231 return 0;
232
233 dev[len - 1] = '\0';
234 return dev + 1;
235 }
236
237 int
238 main (int argc, char *argv[])
239 {
240 char *root_dev = NULL;
241 char *dest_dev = NULL;
242 struct arguments arguments;
243
244 grub_util_host_init (&argc, &argv);
245
246 /* Default option values. */
247 memset (&arguments, 0, sizeof (struct arguments));
248 arguments.fs_probe = 1;
249 arguments.add_rs_codes = 1;
250
251 /* Parse our arguments */
252 if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0)
253 {
254 fprintf (stderr, "%s", _("Error in parsing command line arguments\n"));
255 exit(1);
256 }
257
258 #ifdef GRUB_SETUP_SPARC64
259 arguments.force = 1;
260 #endif
261
262 if (verbosity > 1)
263 grub_env_set ("debug", "all");
264
265 /* Initialize the emulated biosdisk driver. */
266 grub_util_biosdisk_init (arguments.dev_map ? : DEFAULT_DEVICE_MAP);
267
268 /* Initialize all modules. */
269 grub_init_all ();
270 grub_gcry_init_all ();
271
272 grub_lvm_fini ();
273 grub_mdraid09_fini ();
274 grub_mdraid1x_fini ();
275 grub_diskfilter_fini ();
276 grub_diskfilter_init ();
277 grub_mdraid09_init ();
278 grub_mdraid1x_init ();
279 grub_lvm_init ();
280
281 dest_dev = get_device_name (arguments.device);
282 if (! dest_dev)
283 {
284 /* Possibly, the user specified an OS device file. */
285 dest_dev = grub_util_get_grub_dev (arguments.device);
286 if (! dest_dev)
287 {
288 char *program = xstrdup(program_name);
289 fprintf (stderr, _("Invalid device `%s'.\n"), arguments.device);
290 argp_help (&argp, stderr, ARGP_HELP_STD_USAGE, program);
291 free(program);
292 exit(1);
293 }
294 grub_util_info ("transformed OS device `%s' into GRUB device `%s'",
295 arguments.device, dest_dev);
296 }
297 else
298 {
299 /* For simplicity. */
300 dest_dev = xstrdup (dest_dev);
301 grub_util_info ("Using `%s' as GRUB device", dest_dev);
302 }
303
304 /* Do the real work. */
305 GRUB_SETUP_FUNC (arguments.dir ? : DEFAULT_DIRECTORY,
306 arguments.boot_file ? : DEFAULT_BOOT_FILE,
307 arguments.core_file ? : DEFAULT_CORE_FILE,
308 dest_dev, arguments.force,
309 arguments.fs_probe, arguments.allow_floppy,
310 arguments.add_rs_codes);
311
312 /* Free resources. */
313 grub_fini_all ();
314 grub_util_biosdisk_fini ();
315
316 free (arguments.boot_file);
317 free (arguments.core_file);
318 free (arguments.dir);
319 free (arguments.dev_map);
320 free (arguments.device);
321 free (root_dev);
322 free (dest_dev);
323
324 return 0;
325 }