Port-amd64 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: UEFI ExitBootServices



John Nemeth <jnemeth%cue.bc.ca@localhost> wrote:

>      The answer is to check the spec.  I just downloded the latest
> version from uefi.org (I had a slightly older version of it).  The
> only return codes listed for ExitBootServices are success and
> invalid parameter.  The latter will be given if MapKey is incorrect.

Here are below the relevant code in Xen with my debug printf, and the
output.

What is disturbing is that all the information handed to ExitBootServices
was obtained by EFI itself, hence I have trouble to see how my
bootloader could have provided something wrong. Its only 
used contribution here is SystemTable, but it it was corrupted, the
calls to GetMemoryMap whould not even return.

static void __init efi_exit_boot(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *Syste
mTable)
{
    EFI_STATUS status;
    UINTN info_size = 0, map_key;
    bool retry;

PrintStr(L"efi_exit_boot -> efi_bs->GetMemoryMap\r\n");
    efi_bs->GetMemoryMap(&info_size, NULL, &map_key,
                         &efi_mdesc_size, &mdesc_ver);
    info_size += 8 * efi_mdesc_size;
PrintStr(L"efi_exit_boot -> efi_arch_allocate_mmap_buffer\r\n");
    efi_memmap = efi_arch_allocate_mmap_buffer(info_size);
    if ( !efi_memmap )
        blexit(L"Unable to allocate memory for EFI memory map");

    for ( retry = false; ; retry = true )
    {
        efi_memmap_size = info_size;
PrintStr(L"efi_exit_boot -> SystemTable->BootServices->GetMemoryMap\r\n");
        status = SystemTable->BootServices->GetMemoryMap(&efi_memmap_size,
                                                         efi_memmap, &map_key,
                                                         &efi_mdesc_size,
                                                         &mdesc_ver);
        if ( EFI_ERROR(status) )
            PrintErrMesg(L"Cannot obtain memory map", status);

PrintStr(L"efi_exit_boot -> efi_arch_process_memory_map\r\n");
    efi_memmap = efi_arch_allocate_mmap_buffer(info_size);
        efi_arch_process_memory_map(SystemTable, efi_memmap, efi_memmap_size,
                                    efi_mdesc_size, mdesc_ver);

PrintStr(L"efi_exit_boot -> efi_arch_pre_exit_boot\r\n");
        efi_arch_pre_exit_boot();

PrintStr(L"efi_exit_boot -> SystemTable->BootServices->ExitBootServices\r\n");
        status = SystemTable->BootServices->ExitBootServices(ImageHandle,
                                                             map_key);
        efi_bs = NULL;
        if ( status != EFI_INVALID_PARAMETER || retry )
            break;
    }

    if ( EFI_ERROR(status) )
        PrintErrMesg(L"Cannot exit boot services", status);
printk("efi_exit_boot ...\n");

    /* Adjust pointers into EFI. */
    efi_ct = (void *)efi_ct + DIRECTMAP_VIRT_START;
#ifdef USE_SET_VIRTUAL_ADDRESS_MAP
    efi_rs = (void *)efi_rs + DIRECTMAP_VIRT_START;
#endif
    efi_memmap = (void *)efi_memmap + DIRECTMAP_VIRT_START;
    efi_fw_vendor = (void *)efi_fw_vendor + DIRECTMAP_VIRT_START;
printk("efi_exit_boot end\n");
}

And the output:
efi_exit_boot -> efi_bs->GetMemoryMap
efi_exit_boot -> efi_arch_allocate_mmap_buffer
efi_exit_boot -> SystemTable->BootServices->GetMemoryMap
efi_exit_boot -> efi_arch_process_memory_map
efi_exit_boot -> efi_arch_pre_exit_boot
efi_exit_boot -> SystemTable->BootServices->ExitBootServices
efi_exit_boot -> SystemTable->BootServices->GetMemoryMap
efi_exit_boot -> efi_arch_process_memory_map
efi_exit_boot -> efi_arch_pre_exit_boot
efi_exit_boot -> SystemTable->BootServices->ExitBootServices
Cannot exit boot services: ErrCode: 0x8000000000000002



-- 
Emmanuel Dreyfus
http://hcpnet.free.fr/pubz
manu%netbsd.org@localhost


Home | Main Index | Thread Index | Old Index