X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=elilo.c;h=31c7294076b804d8cd55fbb7d91ba7e8d625a0d7;hb=2493c31ec50bffe01fddb3edfa0dd1e9f08e5248;hp=6bdd6bd28a86d781f6451b69f906ac962348b4e0;hpb=8e0034665aa8483b27191c723608575536d01303;p=debian%2Felilo diff --git a/elilo.c b/elilo.c index 6bdd6bd..31c7294 100644 --- a/elilo.c +++ b/elilo.c @@ -1,5 +1,5 @@ /* - * elilo.c - IA-64/IA-32 EFI Linux loader + * elilo.c - IA-64/IA-32/x86_64 EFI Linux loader * * Copyright (C) 1999-2003 Hewlett-Packard Co. * Contributed by David Mosberger . @@ -8,6 +8,11 @@ * Copyright (C) 1999-2000 VA Linux Systems * Contributed by Johannes Erdfelt . * + * Copyright (C) 2006-2009 Intel Corporation + * Contributed by Fenghua Yu + * Contributed by Bibo Mao + * Contributed by Chandramouli Narayanan + * * This file is part of the ELILO, the EFI Linux boot loader. * * ELILO is free software; you can redistribute it and/or modify @@ -41,13 +46,14 @@ #include "loader.h" #include "config.h" /* for config_init() */ -#define ELILO_VERSION L"3.4" #define ELILO_SHARED_CMDLINE_OPTS L"pPMC:aDhd:i:vVc:E" elilo_config_t elilo_opt; EFI_SYSTEM_TABLE *systab; /* pointer to EFI system table */ +extern INTN wait_timeout (UINTN); + /* * Load the Linux kernel in memory from the boot media * Output: @@ -122,11 +128,12 @@ kernel_load(EFI_HANDLE image, CHAR16 *kname, kdesc_t *kd, memdesc_t *imem, memde return ELILO_LOAD_RETRY; } - VERB_PRT(3, Print(L"kernel loaded in [0x%lx-0x%lx] entry=0x%lx\n", - (unsigned long)kd->kstart, (unsigned long)kd->kend, (unsigned long)kd->kentry)); + VERB_PRT(3, Print(L"kernel loaded in [" PTR_FMT "-" PTR_FMT "] entry=" PTR_FMT "\n", + kd->kstart, kd->kend, kd->kentry)); if (elilo_opt.initrd[0]) { + /* ramdisk image is moved to the top of available extended memory later by start_kernel() */ if (sysdeps_initrd_get_addr(kd, imem) == -1) goto exit_error; switch(load_file(elilo_opt.initrd, imem)) { @@ -207,7 +214,7 @@ main_loop(EFI_HANDLE dev, CHAR16 **argv, INTN argc, INTN index, EFI_HANDLE image EFI_STATUS status = EFI_SUCCESS; kdesc_t kd; memdesc_t imem, mmem; - INTN r; + INTN r, retries=0; /* * First place where we potentially do system dependent @@ -237,15 +244,49 @@ do_launch: VERB_PRT(3, Print(L"final cmdline(%d): %s\n", r, cmdline)); + /* Give user time to see the output before launch */ + if (elilo_opt.debug || elilo_opt.verbose) { + r = wait_timeout(150); + /* have to turn off all console output(except error output) now before final get_mmemap() + * call or it can cause the efi map key to change and the ExitBootSvc call to fail, + * forcing debug and verbose options off is the surest way to enforce this. + */ + elilo_opt.debug=0; + elilo_opt.verbose=0; + } + /* free resources associated with file accesses (before ExitBootServices) */ close_devices(); /* No console output permitted after create_boot_params()! */ if ((bp=create_boot_params(cmdline, &imem, &mmem, &cookie)) == 0) goto error; - /* terminate bootservices */ - status = BS->ExitBootServices(image, cookie); - if (EFI_ERROR(status)) goto bad_exit; + /* terminate bootservices + * efi ExitBootSvcs spec: *note, get_memmap is called by create_boot_params() + * An EFI OS loader must ensure that it has the system's current memory map at the time + * it calls ExitBootServices(). This is done by passing in the current memory map's + * MapKey value as returned by GetMemoryMap(). Care must be taken to ensure that the + * memory map does not change between these two calls. It is suggested that + * GetMemoryMap()be called immediately before calling ExitBootServices(). */ + +retry: + status = uefi_call_wrapper(BS->ExitBootServices, 2, image, cookie); + if (EFI_ERROR(status)) + { + ERR_PRT((L"\nExitBootSvcs: failed, memory map has changed.\n")); + if (retries < 2) + { + ERR_PRT((L"Main_Loop: Retrying,... have to rebuild boot params")); + retries++; + free_boot_params(bp); + if ((bp=create_boot_params(cmdline, &imem, &mmem, &cookie)) == 0) goto error; + goto retry; + } else { + ERR_PRT((L"\nMain_Loop: tried ExitBootSvcs 3 times... retries exceeded.... giving up\n")); + goto bad_exit; + } + } + start_kernel(kd.kentry, bp); /* NOT REACHED */ @@ -259,6 +300,7 @@ bad_exit: error: free_kmem(); if (imem.start_addr) free(imem.start_addr); + if (mmem.start_addr) free(mmem.start_addr); if (bp) free_boot_params(bp); exit_error: return ELILO_LOAD_ERROR; @@ -307,7 +349,7 @@ fixupargs(EFI_LOADED_IMAGE *info) #define FAKE_ELILONAME L"elilo-forced" - status = BS->HandleProtocol (info->DeviceHandle, &PxeBaseCodeProtocol, (VOID **)&pxe); + status = uefi_call_wrapper(BS->HandleProtocol, 3, info->DeviceHandle, &PxeBaseCodeProtocol, (VOID **)&pxe); if (EFI_ERROR(status)) return; default_load_options = info->LoadOptions; @@ -365,7 +407,7 @@ check_edd30(VOID) UINT8 bool = FALSE; INTN ret = -1; - status = RT->GetVariable(L"EDD30", &edd30_guid, NULL, &l, &bool); + status = uefi_call_wrapper(RT->GetVariable, 5, L"EDD30", &edd30_guid, NULL, &l, &bool); if (status == EFI_BUFFER_TOO_SMALL || (bool != TRUE && bool != FALSE)) { ERR_PRT((L"Warning: EDD30 EFI variable is not boolean value: forcing it to TRUE")); return -1; @@ -395,7 +437,7 @@ force_edd30(VOID) UINT8 bool; bool = TRUE; - status = RT->SetVariable(L"EDD30", &edd30_guid, EDD30_ATTR, l, &bool); + status = uefi_call_wrapper(RT->SetVariable, 5, L"EDD30", &edd30_guid, EDD30_ATTR, l, &bool); if (EFI_ERROR(status)) { ERR_PRT((L"can't set EDD30 variable: ignoring it")); return -1; @@ -439,19 +481,18 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *system_tab) * mode. * XXX: clean this up ! */ - BS->SetWatchdogTimer(0, 0x0, 0, NULL); + uefi_call_wrapper(BS->SetWatchdogTimer, 4, 0, 0x0, 0, NULL); /* initialize memory allocator */ if (alloc_init() == -1) return EFI_LOAD_ERROR; - status = BS->HandleProtocol(image, &LoadedImageProtocol, (VOID **) &info); + status = uefi_call_wrapper(BS->HandleProtocol, 3, image, &LoadedImageProtocol, (VOID **) &info); if (EFI_ERROR(status)) { ERR_PRT((L"image handle does not support LOADED_IMAGE protocol")); return EFI_LOAD_ERROR; } - 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)); - + 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)); /* * verify EDD3.0 status. Users may have to reboot */ @@ -595,7 +636,7 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *system_tab) goto do_exit; } } - DBG_PRT((L"Optind=%d optarg=%x argc=%d", Optind, Optarg, argc)); + DBG_PRT((L"Optind=%d optarg=" PTR_FMT " argc=%d", Optind, Optarg, argc)); /* * we can't defer this phase any longer...