Imported Upstream version 3.10
[debian/elilo] / elilo.c
1 /* 
2  * elilo.c - IA-64/IA-32/x86_64 EFI Linux loader
3  *
4  *  Copyright (C) 1999-2003 Hewlett-Packard Co.
5  *      Contributed by David Mosberger <davidm@hpl.hp.com>.
6  *      Contributed by Stephane Eranian <eranian@hpl.hp.com>
7  *
8  *  Copyright (C) 1999-2000 VA Linux Systems
9  *       Contributed by Johannes Erdfelt <jerdfelt@valinux.com>.
10  *
11  *  Copyright (C) 2006-2009 Intel Corporation
12  *      Contributed by Fenghua Yu <fenghua.yu@intel.com>
13  *      Contributed by Bibo Mao <bibo.mao@intel.com>
14  *      Contributed by Chandramouli Narayanan <mouli@linux.intel.com>
15  *
16  * This file is part of the ELILO, the EFI Linux boot loader.
17  *
18  *  ELILO is free software; you can redistribute it and/or modify
19  *  it under the terms of the GNU General Public License as published by
20  *  the Free Software Foundation; either version 2, or (at your option)
21  *  any later version.
22  *
23  *  ELILO is distributed in the hope that it will be useful,
24  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
25  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  *  GNU General Public License for more details.
27  *
28  *  You should have received a copy of the GNU General Public License
29  *  along with ELILO; see the file COPYING.  If not, write to the Free
30  *  Software Foundation, 59 Temple Place - Suite 330, Boston, MA
31  *  02111-1307, USA.
32  *
33  * Please check out the elilo.txt for complete documentation on how
34  * to use this program.
35  */
36
37 #include <efi.h>
38 #include <efilib.h>
39
40 #include "elilo.h"
41 #include "vars.h"
42 #include "gzip.h"
43
44 #include "getopt.h"
45 #include "fileops.h"
46 #include "loader.h"
47 #include "config.h" /* for config_init() */
48
49 #define ELILO_VERSION                   L"3.10"
50 #define ELILO_SHARED_CMDLINE_OPTS       L"pPMC:aDhd:i:vVc:E"
51
52 elilo_config_t elilo_opt;
53
54 EFI_SYSTEM_TABLE *systab;       /* pointer to EFI system table */
55
56 extern INTN wait_timeout (UINTN);
57
58 /*
59  * Load the Linux kernel in memory from the boot media
60  * Output:
61  *      kd = address of kernel entry point
62  *         + end address of kernel code+data+bss
63  *         + kernel entry point
64  * Return:
65  *      ELILO_LOAD_ERROR   : if something went wrong
66  *      ELILO_LOAD_ABORTED : user interruption while loading
67  *      ELILO_LOAD_SUCCESS : otherwise
68  */
69 static INTN
70 do_kernel_load(CHAR16 *kname, kdesc_t *kd)
71 {
72         loader_ops_t    *ldops;
73         EFI_STATUS status;
74         fops_fd_t fd;
75
76         status = fops_open(kname, &fd);
77         if (EFI_ERROR(status)) {
78                 ERR_PRT((L"Kernel file  not found %s", kname));
79                 return ELILO_LOAD_ERROR;
80         }
81         fops_close(fd);
82
83         ldops = loader_probe(kname);
84         if (ldops == NULL) {
85                 ERR_PRT((L"Cannot find a loader for %s", kname));
86                 return ELILO_LOAD_ERROR;
87         }
88
89         VERB_PRT(1,Print(L"Using %s loader\n", ldops->ld_name));
90         
91         return ldops->ld_load_kernel(kname, kd);
92 }
93
94 INTN
95 kernel_load(EFI_HANDLE image, CHAR16 *kname, kdesc_t *kd, memdesc_t *imem, memdesc_t *mmem)
96 {
97         CHAR16 kernel[CMDLINE_MAXLEN];
98
99         /*
100          * Do the vm image switch here
101          * if there is "vmm=" then elilo should load image specified
102          * in "vmm=" and then give the "image" to vmm as target kernel image
103          */
104         if (elilo_opt.vmcode[0])
105                 StrCpy(kernel, elilo_opt.vmcode);
106         else
107                 StrCpy(kernel, kname);
108         /*
109          * Now let's try to load the kernel !
110          */
111         switch(do_kernel_load(kernel, kd)) {
112                 case ELILO_LOAD_SUCCESS:
113                         break;
114
115                 case ELILO_LOAD_ERROR:
116                         /* XXX: add fallback support */
117                         return ELILO_LOAD_ERROR;
118                 
119                 case ELILO_LOAD_ABORTED:
120                         /* we drop initrd in case we aborted the load */
121                         elilo_opt.initrd[0] = CHAR_NULL;
122                         elilo_opt.vmcode[0] = CHAR_NULL;
123
124                         /* will go back to interactive selection */
125                         elilo_opt.prompt  = 1; 
126                         elilo_opt.timeout = ELILO_DEFAULT_TIMEOUT;
127                         elilo_opt.delay   = 0;
128
129                         return ELILO_LOAD_RETRY;        
130         }
131
132         VERB_PRT(3, Print(L"kernel loaded in [" PTR_FMT "-" PTR_FMT "] entry=" PTR_FMT "\n", 
133                           kd->kstart, kd->kend, kd->kentry));
134
135         if (elilo_opt.initrd[0]) {
136
137                 /* ramdisk image is moved to the top of available extended memory later by start_kernel() */
138                 if (sysdeps_initrd_get_addr(kd, imem) == -1) goto exit_error;
139
140                 switch(load_file(elilo_opt.initrd, imem)) {
141                         case ELILO_LOAD_SUCCESS:
142                                 break;
143                         case ELILO_LOAD_ERROR:
144                                 goto exit_error;
145                         case ELILO_LOAD_ABORTED:
146                                 free_kmem();
147                                 /* we drop initrd in case we aborted the load */
148                                 elilo_opt.initrd[0] = CHAR_NULL;
149                                 elilo_opt.vmcode[0] = CHAR_NULL;
150                                 elilo_opt.prompt    = 1; 
151                                 elilo_opt.timeout   = ELILO_DEFAULT_TIMEOUT;
152                                 elilo_opt.delay     = 0;
153
154                                 return ELILO_LOAD_RETRY;
155                 }
156         }
157
158         if (elilo_opt.vmcode[0]) {
159
160                 mmem->start_addr = 0; /* let the allocator decide */
161
162                 switch(load_file(kname, mmem)) {
163                         case ELILO_LOAD_SUCCESS:
164                                 break;
165                         case ELILO_LOAD_ERROR:
166                                 goto exit_error;
167                         case ELILO_LOAD_ABORTED:
168                                 if (imem->start_addr)
169                                         free(imem->start_addr);
170                                 free_kmem();
171                                 /* we drop initrd in case we aborted the load */
172                                 elilo_opt.initrd[0] = CHAR_NULL;
173                                 elilo_opt.vmcode[0] = CHAR_NULL;
174                                 elilo_opt.prompt    = 1; 
175                                 elilo_opt.timeout   = ELILO_DEFAULT_TIMEOUT;
176                                 elilo_opt.delay     = 0;
177
178                                 return ELILO_LOAD_RETRY;
179                 }
180
181                 /* Test for a compressed image and unzip if found */
182                 if (gzip_probe(mmem->start_addr, mmem->size) == 0 &&
183                     gunzip_image(mmem) != ELILO_LOAD_SUCCESS) {
184                         if (imem->start_addr)
185                                 free(imem->start_addr);
186                         free(mmem->start_addr);
187                         free_kmem();
188                         /* we drop initrd in case we aborted the load */
189                         elilo_opt.initrd[0] = CHAR_NULL;
190                         elilo_opt.vmcode[0] = CHAR_NULL;
191                         elilo_opt.prompt    = 1; 
192                         elilo_opt.timeout   = ELILO_DEFAULT_TIMEOUT;
193                         elilo_opt.delay     = 0;
194
195                         return ELILO_LOAD_RETRY;
196                 }
197         }
198         return ELILO_LOAD_SUCCESS;
199 exit_error:
200         free_kmem();
201         if (imem->start_addr) free(imem->start_addr);
202         if (mmem->start_addr) free(mmem->start_addr);
203
204         return ELILO_LOAD_ERROR;
205 }
206
207 static INTN
208 main_loop(EFI_HANDLE dev, CHAR16 **argv, INTN argc, INTN index, EFI_HANDLE image)
209 {
210         CHAR16 kname[FILENAME_MAXLEN];
211         CHAR16 cmdline_tmp[CMDLINE_MAXLEN];
212         CHAR16 cmdline[CMDLINE_MAXLEN];
213         VOID *bp;
214         UINTN cookie;
215         EFI_STATUS status = EFI_SUCCESS;
216         kdesc_t kd;
217         memdesc_t imem, mmem;
218         INTN r;
219
220         /*
221          * First place where we potentially do system dependent
222          * operations. It is a one time opportunity before entering
223          * the main loop
224          */
225         if (sysdeps_preloop_actions(dev, argv, argc, index, image) == -1) return -1;
226
227         for(;;) {
228                 kname[0] = cmdline_tmp[0] = cmdline[0] = CHAR_NULL;
229                 imem.start_addr = 0; imem.pgcnt = 0; imem.size = 0;
230                 elilo_opt.sys_img_opts = NULL;
231
232                 if (kernel_chooser(argv, argc, index, kname, cmdline_tmp) == -1) goto exit_error;
233
234                 switch (kernel_load(image, kname, &kd, &imem, &mmem)) {
235                         case ELILO_LOAD_SUCCESS: 
236                                 goto do_launch;
237                         case ELILO_LOAD_ERROR:
238                                 goto exit_error;
239                         /* otherwise we retry ! */
240                 }
241         } 
242
243 do_launch:
244         r =subst_vars(cmdline_tmp, cmdline, CMDLINE_MAXLEN);
245
246         VERB_PRT(3, Print(L"final cmdline(%d): %s\n", r, cmdline));
247
248         /* Give user time to see the output before launch */
249         if (elilo_opt.debug || elilo_opt.verbose) r = wait_timeout(300);
250
251         /* free resources associated with file accesses (before ExitBootServices) */
252         close_devices();
253
254         /* No console output permitted after create_boot_params()! */
255         if ((bp=create_boot_params(cmdline, &imem, &mmem, &cookie)) == 0) goto error;
256
257         /* terminate bootservices */
258         status = uefi_call_wrapper(BS->ExitBootServices, 2, image, cookie);
259         if (EFI_ERROR(status)) goto bad_exit;
260
261         start_kernel(kd.kentry, bp);
262         /* NOT REACHED */
263
264         ERR_PRT((L"start_kernel() return !"));
265 bad_exit:       
266         /*
267          * we are still in BootService mode
268          */
269         ERR_PRT((L"ExitBootServices failed %r", status));
270 error:
271         free_kmem();
272         if (imem.start_addr) free(imem.start_addr);
273         if (bp) free_boot_params(bp);
274 exit_error:
275         return ELILO_LOAD_ERROR;
276
277 }
278
279 static VOID
280 elilo_help(VOID)
281 {
282         
283         Print(L"-d secs   timeout in 10th of second before booting\n");
284         Print(L"-h        this help text\n");
285         Print(L"-V        print version\n");
286         Print(L"-v        verbose level(can appear multiple times)\n");
287         Print(L"-a        always check for alternate kernel image\n");
288         Print(L"-i file   load file as the initial ramdisk\n");
289         Print(L"-m file   load file as additional boot time vmm module\n");
290         Print(L"-C file   indicate the config file to use\n");
291         Print(L"-P        parse config file only (verify syntax)\n");
292         Print(L"-D        enable debug prints\n");
293         Print(L"-p        force interactive mode\n");
294         Print(L"-c name   image chooser to use\n");
295         Print(L"-E        do not force EDD30 variable\n");
296
297         sysdeps_print_cmdline_opts();
298
299         Print(L"\n");
300
301         print_config_options();
302 }
303
304 /*
305  * XXX: hack to work around a problem with EFI command line argument when booted
306  * from network. In this case, it looks like LoadOptions/LoadOptionsSize contain
307  * garbage
308  */
309 static CHAR16 *default_load_options;
310 static UINTN default_load_options_size;
311 static INTN done_fixups;
312
313 static VOID
314 fixupargs(EFI_LOADED_IMAGE *info)
315 {
316         EFI_STATUS status;
317         EFI_PXE_BASE_CODE *pxe;
318
319 #define FAKE_ELILONAME  L"elilo-forced"
320
321         status = uefi_call_wrapper(BS->HandleProtocol, 3, info->DeviceHandle, &PxeBaseCodeProtocol, (VOID **)&pxe);
322         if (EFI_ERROR(status)) return;
323
324         default_load_options      = info->LoadOptions;
325         default_load_options_size = info->LoadOptionsSize;
326
327         info->LoadOptions     = FAKE_ELILONAME;
328         info->LoadOptionsSize = StrLen(info->LoadOptions)*sizeof(CHAR16);
329
330         done_fixups = 1;
331 }
332
333 /*
334  * we restore the arguments in case we modified them just to make sure
335  * we don't confuse caller.
336  */
337 static VOID
338 unfixupargs(EFI_LOADED_IMAGE *info)
339 {
340         if (done_fixups == 0) return;
341
342         info->LoadOptions     = default_load_options;
343         info->LoadOptionsSize = default_load_options_size;
344 }
345
346
347 /*
348  * in order to get fully detailed EFI path names to devices, EDD3.0 specification must
349  * be turned on. On new versions of EFI, this is the default. An environment variable
350  * called EDD30 reflects the current settings. If true, then EDD3.0 is enabled 
351  * and device path names show the detailed device types. If false, then a default 
352  * generic name is used instead. This has some implications of ELILO's ability to 
353  * provide a better naming scheme for detected devices. If EDD3.0 is enabled
354  * then much more precise names can be used which makes it easy to use. 
355  * If EDD3.0 is nont enabled, ELILO will still work but will use very generic names
356  * for devices.
357  *
358  * ELILO will check the value of the variable. If not true, then it will force it to
359  * true. This will require a reboot for EFI to make use of the new value.
360  * Return:
361  *      EFI_SUCCESS: if variable is already true or was set to true
362  *      EFI error code: otherwise, like when could not forced variable or unrecognized variable content
363  */
364 #define EDD30_GUID \
365 {0x964e5b21, 0x6459, 0x11d2, { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b}}
366
367 #define EDD30_ATTR (EFI_VARIABLE_RUNTIME_ACCESS|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_NON_VOLATILE)
368
369 static EFI_GUID edd30_guid = EDD30_GUID;
370
371 static INTN
372 check_edd30(VOID)
373 {
374         EFI_STATUS      status;
375         UINTN           l = sizeof(BOOLEAN);
376         UINT8           bool = FALSE;
377         INTN            ret = -1;
378
379         status = uefi_call_wrapper(RT->GetVariable, 5, L"EDD30", &edd30_guid, NULL, &l, &bool);
380         if (status == EFI_BUFFER_TOO_SMALL || (bool != TRUE && bool != FALSE)) {
381                 ERR_PRT((L"Warning: EDD30 EFI variable is not boolean value: forcing it to TRUE"));
382                 return -1;
383         }
384         if (status == EFI_SUCCESS && bool == TRUE) {
385                 VERB_PRT(3, Print(L"EDD30 is TRUE\n"));
386                 elilo_opt.edd30_on = TRUE;
387                 ret = 0;
388         } else {
389                 VERB_PRT(4, 
390                         if (status != EFI_SUCCESS) {
391                                 Print(L"EDD30 EFI variable not defined\n");
392                         } else {
393                                 Print(L"EDD30 EFI variable is false\n");
394                         }
395                 );
396         }
397
398         return ret;
399 }
400
401 static INTN
402 force_edd30(VOID)
403 {
404         EFI_STATUS      status;
405         UINTN           l = sizeof(BOOLEAN);
406         UINT8           bool;
407
408         bool = TRUE;
409         status = uefi_call_wrapper(RT->SetVariable, 5, L"EDD30", &edd30_guid, EDD30_ATTR, l, &bool);
410         if (EFI_ERROR(status)) {
411                 ERR_PRT((L"can't set EDD30 variable: ignoring it"));
412                 return -1;
413         }
414
415         VERB_PRT(3, Print(L"EDD30 variable forced to TRUE. You should reboot to take advantage of EDD3.0.\n"));
416
417         return 0;
418 }
419
420 /*
421  * That's equivalent of main(): main entry point
422  */
423 EFI_STATUS
424 efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *system_tab)
425 {
426         CHAR16 *argv[MAX_ARGS];
427         CHAR16 optstring[MAX_ARGS];
428         EFI_LOADED_IMAGE *info;
429         EFI_STATUS status, ret = EFI_LOAD_ERROR;
430         INTN argc = 0, c;
431         INTN edd30_status, retry;
432         CHAR16 *ptr, *arglist = NULL;
433         BOOLEAN devices_initialized = FALSE;
434         CHAR16 dpath[FILENAME_MAXLEN];
435         CHAR16 *devpath;
436
437         elilo_opt.verbose=0;
438         elilo_opt.debug=0;
439
440         /* initialize global variable */
441         systab = system_tab;
442         
443         /* initialize EFI library */
444         InitializeLib(image, systab);
445         /*
446          * disable the platform watchdog timer if we go interactive
447          * XXX: we should reinstate it once we're done
448          * It seems like with PXE, the timer is set to a few minutes
449          * and sometimes triggers if we stay too long in interactive
450          * mode.
451          * XXX: clean this up !
452          */
453        uefi_call_wrapper(BS->SetWatchdogTimer, 4, 0, 0x0, 0, NULL);
454
455         /* initialize memory allocator */
456         if (alloc_init() == -1) return EFI_LOAD_ERROR;
457
458         status = uefi_call_wrapper(BS->HandleProtocol, 3, image, &LoadedImageProtocol, (VOID **) &info);
459         if (EFI_ERROR(status)) {
460                 ERR_PRT((L"image handle does not support LOADED_IMAGE protocol"));
461                 return EFI_LOAD_ERROR;
462         }
463
464         VERB_PRT(5,Print(L"Loaded at " PTR_FMT " size=%ld bytes code=%d data=%d\n", info->ImageBase, info->ImageSize, info->ImageCodeType, info->ImageDataType));
465         /*
466          * verify EDD3.0 status. Users may have to reboot 
467          */
468         edd30_status = check_edd30();
469
470         /*
471          * initialize configuration empire
472          */
473         if (config_init() == -1) goto do_exit;
474
475         /* 
476          * architecture-specific initializations
477          */
478         if (sysdeps_init(info->DeviceHandle) == -1) goto do_exit;
479         if (sysdeps_register_options() == -1) goto do_exit;
480
481         /*
482          * This may be required in case Elilo was booted with absolutely no arguments
483          * Elilo's logic is that just like normal Linux programs at least one argument
484          * (argv[0]) exists at all times and that it usually gives the name of the program
485          * (the command used to start it).
486         ERR_PRT((L"LoadOptions=%x OpenSize=%d", info->LoadOptions, info->LoadOptionsSize));
487          */
488
489         /*
490          * in case there is something wrong with the default boot_device
491          * we default to basic fixups and we need to force interactive
492          * mode to make sure the user has a chance of specifying a kernel
493          */
494         fixupargs(info);
495
496 #if 0
497         Print(L"LoadOptions=%x OpenSize=%d\n", info->LoadOptions, info->LoadOptionsSize);
498         { INTN i; for (i=0; i< info->LoadOptionsSize>>1; i++) Print(L"options[%d]=%d (%c)\n", i, ((CHAR16 *)info->LoadOptions)[i], ((CHAR16 *)info->LoadOptions)[i]); }
499 #endif
500
501         /*
502          * we must copy argument because argify modifies the string.
503          * This caused problems when arguments are coming from NVRAM
504          * as passed by the EFI boot manager
505          *
506          * We add an extra character to the buffer in case the LoadOptions is not 
507          * NULL terminated. The extra space will be used to ADD the extra terminator.
508          */
509         arglist = alloc(info->LoadOptionsSize+sizeof(CHAR16), EfiLoaderData);
510         if (arglist == NULL) {
511                 ERR_PRT((L"cannot copy argument list"));
512                 return EFI_OUT_OF_RESOURCES;
513         }
514         Memcpy(arglist, info->LoadOptions, info->LoadOptionsSize);
515
516         argc = argify(arglist,info->LoadOptionsSize, argv); 
517
518         StrCpy(optstring, ELILO_SHARED_CMDLINE_OPTS);
519         StrCat(optstring, sysdeps_get_cmdline_opts());
520
521         while ((c=Getopt(argc, argv, optstring)) != -1 ) {
522                 switch(c) {
523                         case 'a':
524                                 elilo_opt.alt_check = 1;
525                                 break;
526                         case 'D':
527                                 elilo_opt.debug = 1;
528                                 break;
529                         case 'p':
530                                 elilo_opt.prompt = 1;
531                                 break;
532                         case 'v':
533                                 elilo_opt.verbose++;
534                                 if (elilo_opt.verbose > 5) elilo_opt.verbose = 5;
535                                 break;
536                         case 'h':
537                                 elilo_help();
538                                 ret = EFI_SUCCESS;
539                                 goto do_exit;
540                         case 'd':
541                                 /*
542                                  * zero is a valid value here, so we use the delay-set to mark the
543                                  * fact that the user specified a value on cmdline. See config.c
544                                  */
545                                 elilo_opt.delay = Atoi(Optarg);
546                                 elilo_opt.delay_set = 1;
547                                 break;
548                         case 'E':
549                                 /* don't force EDD30 EFI variable if not already set */
550                                 elilo_opt.edd30_no_force = 1;
551                                 break;
552                         case 'i':
553                                 if (StrLen(Optarg) >= FILENAME_MAXLEN-1) {
554                                         Print(L"initrd filename is limited to %d characters\n", FILENAME_MAXLEN);
555                                         goto do_exit;
556                                 }
557                                 StrCpy(elilo_opt.initrd, Optarg);
558                                 break;
559                         case 'm':
560                                 if (StrLen(Optarg) >= FILENAME_MAXLEN-1) {
561                                         Print(L"vmm module filename is limited to %d characters\n", FILENAME_MAXLEN);
562                                         goto do_exit;
563                                 }
564                                 StrCpy(elilo_opt.vmcode, Optarg);
565                                 break;
566                         case 'C':
567                                 if (StrLen(Optarg) >= FILENAME_MAXLEN-1) {
568                                         Print(L"config filename is limited to %d characters\n", FILENAME_MAXLEN);
569                                         goto do_exit;
570                                 }
571                                 StrCpy(elilo_opt.config, Optarg);
572                                 break;
573                         case 'M': /* builtin debug tool */
574                                 { mmap_desc_t mdesc; 
575                                         if (get_memmap(&mdesc) == -1) {
576                                                 Print(L"Cannot get memory map\n");
577                                                 return EFI_LOAD_ERROR;
578                                         }
579                                         print_memmap(&mdesc);
580                                         ret = EFI_SUCCESS;
581                                         goto do_exit;
582                                 }
583                         case 'V':
584                                 Print(L"ELILO v%s for EFI/%a\n", ELILO_VERSION, ELILO_ARCH);
585                                 ret = EFI_SUCCESS;
586                                 goto do_exit;
587                         case 'P':
588                                 /* cmdline only option */
589                                 elilo_opt.parse_only =  1;
590                                 break;
591                         case 'c':
592                                 if (StrLen(Optarg) >= FILENAME_MAXLEN-1) {
593                                         Print(L"chooser name is limited to %d characters\n", FILENAME_MAXLEN);
594                                         goto do_exit;
595                                 }
596                                 StrCpy(elilo_opt.chooser, Optarg);
597                                 break;
598                         default:
599                                 /*
600                                  * try system dependent options before declaring error
601                                  */
602                                 if (sysdeps_getopt(c, Optind, Optarg) == 0) continue;
603
604                                 Print(L"Unknown option -%c\n", (CHAR16)c);
605                                 goto do_exit;
606                 }
607         }
608         DBG_PRT((L"Optind=%d optarg=" PTR_FMT " argc=%d", Optind, Optarg, argc));
609
610         /*
611          * we can't defer this phase any longer...
612          * Must be done after the elilo_opt are initialized (at least partially)
613          */
614         if (init_devices(info->DeviceHandle) == -1) goto do_exit;
615
616         devices_initialized = TRUE;
617
618         devpath = DevicePathToStr(info->FilePath);
619
620         /*
621          * set per fileops defaults files for configuration and kernel
622          */
623         fops_setdefaults(elilo_opt.default_configs, elilo_opt.default_kernel, FILENAME_MAXLEN, devpath);
624
625         /*
626          * XXX: won't be visible if verbose not required from command line
627          */
628         VERB_PRT(2,Print(L"Default config: %s\nDefault_kernel: %s\n",
629                         elilo_opt.default_configs[0].fname, elilo_opt.default_kernel));
630         /*
631          * use default config file if not specified by user
632          */
633         ptr = elilo_opt.config[0] == CHAR_NULL ?  (retry=1,elilo_opt.default_configs[0].fname) : (retry=0,elilo_opt.config);
634
635         /*
636          * parse config file (verbose becomes visible if set)
637          */
638         ret = read_config(ptr);
639         VERB_PRT(1,Print(L"read_config=%r\n", ret));
640
641         /* Only try the default config filenames if user did not specify a
642          * config filename on the command line */
643         if (elilo_opt.config[0] == CHAR_NULL) {
644                 while ((ret != EFI_SUCCESS) &&
645                        (retry < MAX_DEFAULT_CONFIGS) &&
646                        (elilo_opt.default_configs[retry].fname[0] != CHAR_NULL)) {
647
648                         ptr = elilo_opt.default_configs[retry].fname;
649                         ret = read_config(ptr);
650                         VERB_PRT(1,Print(L"read_config=%r\n", ret));
651                         retry += 1;
652                 }
653         }
654         /*
655          * when the config file is not found, we fail only if:
656          *      - the user did not specified interactive mode
657          *      - the user did not explicitely specify the config file
658          */
659         if (ret == EFI_NOT_FOUND || ret == EFI_TFTP_ERROR) {
660                 if (elilo_opt.prompt == 0 && elilo_opt.config[0] != CHAR_NULL) {
661                         Print(L"config file %s not found\n", ptr);
662                         goto do_exit;
663                 }
664                 fops_getdefault_path(dpath, FILENAME_MAXLEN);
665                 if (ret == EFI_TFTP_ERROR)
666                         Print(L"no config file found on TFTP server in %s\n", dpath);
667                 else
668                         Print(L"no config file found in %s\n", dpath);
669         }
670         /*
671          * stop if just doing parsing
672          */
673         if (elilo_opt.parse_only) {
674                 if (ret == EFI_SUCCESS)
675                         Print(L"Config file %s parsed successfully\n", ptr);
676                 goto do_exit;
677         }
678         /*
679          * if there was an error when parsing the config file, then
680          * we force interactive mode to give a chance to the user.
681          * We also clear the error. 
682          */
683         if (ret != EFI_SUCCESS) {
684                 Print(L"forcing interactive mode due to config file error(s)\n");
685                 elilo_opt.prompt = 1;
686         }
687         /*
688          * However, if the user specified a kernel on the command line
689          * then we don't go to interactive mode, even if there was an option in
690          * the config file telling us to do so.
691          */
692         if (argc > Optind) {
693             elilo_opt.prompt = 0;
694         }
695
696         /*
697          * If EDD30 EFI variable was not set to TRUE (or not defined), we
698          * we try to force it. This will take effect at the next reboot.
699          *
700          * Some controllers don't have EDD30 support, in this case forcing it 
701          * may cause problems, therefore we check the edd_no_force option
702          * before making the call.
703          */
704         if (edd30_status == -1 && elilo_opt.edd30_no_force == 0) {
705                 force_edd30();
706         }
707
708         ret = EFI_LOAD_ERROR;
709
710
711
712         /* set default timeout if going interactive */
713         if ((elilo_opt.prompt && elilo_opt.timeout == 0)) {
714                 elilo_opt.timeout = ELILO_DEFAULT_TIMEOUT;
715         }
716
717         /*
718          * which chooser we will use 
719          */
720         if (init_chooser(info->DeviceHandle) == -1) {
721                 ERR_PRT((L"Cannot find a decent chooser\n"));
722                 goto do_exit;
723         }
724
725         //if (elilo_opt.prompt == 0) VERB_PRT(1, print_devices());
726
727         main_loop(info->DeviceHandle, argv, argc, Optind, image);
728         /* should not return */
729 do_exit:
730         unfixupargs(info);
731
732         //if (arglist) free(arglist);
733
734         /* free all resources assiocated with file accesses */
735         if (devices_initialized) close_devices();
736
737         /* garbage collect all remaining allocations */
738         free_all_memory();
739
740         return ret;
741 }