2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc.
5 * GRUB is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * GRUB is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
26 #include <sys/types.h>
31 #include <grub/setjmp.h>
33 #include <grub/emu/hostdisk.h>
34 #include <grub/time.h>
35 #include <grub/emu/console.h>
36 #include <grub/emu/misc.h>
37 #include <grub/kernel.h>
38 #include <grub/normal.h>
39 #include <grub/emu/getroot.h>
41 #include <grub/partition.h>
42 #include <grub/i18n.h>
47 #define ENABLE_RELOCATABLE 0
49 /* Used for going back to the main function. */
50 static jmp_buf main_env
;
52 /* Store the prefix specified by an argument. */
53 static char *root_dev
= NULL
, *dir
= NULL
;
57 grub_addr_t grub_modbase
= 0;
62 longjmp (main_env
, 1);
66 grub_machine_init (void)
71 grub_machine_get_bootlocation (char **device
, char **path
)
78 grub_machine_fini (void)
85 static struct argp_option options
[] = {
86 {"root", 'r', N_("DEVICE_NAME"), 0, N_("Set root device."), 2},
87 {"device-map", 'm', N_("FILE"), 0,
88 /* TRANSLATORS: There are many devices in device map. */
89 N_("use FILE as the device map [default=%s]"), 0},
90 {"directory", 'd', N_("DIR"), 0,
91 N_("use GRUB files in the directory DIR [default=%s]"), 0},
92 {"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
93 {"hold", 'H', N_("SECS"), OPTION_ARG_OPTIONAL
, N_("wait until a debugger will attach"), 0},
98 help_filter (int key
, const char *text
, void *input
__attribute__ ((unused
)))
103 return xasprintf (text
, DEFAULT_DIRECTORY
);
105 return xasprintf (text
, DEFAULT_DEVICE_MAP
);
107 return (char *) text
;
118 argp_parser (int key
, char *arg
, struct argp_state
*state
)
120 /* Get the input argument from argp_parse, which we
121 know is a pointer to our arguments structure. */
122 struct arguments
*arguments
= state
->input
;
128 root_dev
= xstrdup (arg
);
135 arguments
->dev_map
= arg
;
138 arguments
->hold
= (arg
? atoi (arg
) : -1);
146 /* Too many arguments. */
147 fprintf (stderr
, _("Unknown extra argument `%s'."), arg
);
148 fprintf (stderr
, "\n");
154 return ARGP_ERR_UNKNOWN
;
159 static struct argp argp
= {
160 options
, argp_parser
, NULL
,
161 N_("GRUB emulator."),
162 NULL
, help_filter
, NULL
167 void grub_hostfs_init (void);
168 void grub_hostfs_fini (void);
169 void grub_host_init (void);
170 void grub_host_fini (void);
171 void grub_emu_init (void);
174 main (int argc
, char *argv
[])
176 struct arguments arguments
=
178 .dev_map
= DEFAULT_DEVICE_MAP
,
181 volatile int hold
= 0;
183 set_program_name (argv
[0]);
185 dir
= xstrdup (DEFAULT_DIRECTORY
);
187 if (argp_parse (&argp
, argc
, argv
, 0, 0, &arguments
) != 0)
189 fprintf (stderr
, "%s", _("Error in parsing command line arguments\n"));
193 hold
= arguments
.hold
;
194 /* Wait until the ARGS.HOLD variable is cleared by an attached debugger. */
195 if (hold
&& verbosity
> 0)
196 /* TRANSLATORS: In this case GRUB tells user what he has to do. */
197 printf (_("Run `gdb %s %d', and set ARGS.HOLD to zero.\n"),
198 program_name
, (int) getpid ());
207 signal (SIGINT
, SIG_IGN
);
209 grub_console_init ();
212 /* XXX: This is a bit unportable. */
213 grub_util_biosdisk_init (arguments
.dev_map
);
219 grub_emu_post_init ();
221 /* Make sure that there is a root device. */
223 root_dev
= grub_strdup ("host");
228 if (setjmp (main_env
) == 0)
235 grub_machine_fini ();
243 grub_millisleep (grub_uint32_t ms
)
251 grub_millisleep (grub_uint32_t ms
)
255 ts
.tv_sec
= ms
/ 1000;
256 ts
.tv_nsec
= (ms
% 1000) * 1000000;
257 nanosleep (&ts
, NULL
);