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