help-grub
[Top][All Lists]
Advanced

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

Re: "couldn't terminate EFI services" error caused by buggy BIOS and the


From: Andrei Borzenkov
Subject: Re: "couldn't terminate EFI services" error caused by buggy BIOS and the workaround
Date: Mon, 27 Oct 2014 06:25:22 +0300

В Mon, 27 Oct 2014 10:25:59 +0800
Wang Weber <address@hidden> пишет:

> Hi,
> 
> I am using grub-1.99 on a x86 platform.

Please tets current GIT master, it should be fixed there. If not,
report to grub-devel.

>                                        The BIOS is originated from AMI and
> customized a little by our company. When booting up Linux 3.X, I can see
> the error message "couldn't terminate EFI services".
> 
> According to the colaberate debug by both SW/FW side, it is found that
> before grub calls EFI API exit_boot_services(), the internal finish_key is
> changed. See the following code and notes for details.
> 
> 
> Code from GRUB-1.99
> =====================================
> 
>   if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf,
> &finish_key,
>                                &finish_desc_size, &finish_desc_version) < 0)
>     return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
>   if (outbuf && *outbuf_size < finish_mmap_size)
>     return grub_error (GRUB_ERR_IO, "memory map buffer is too small");
>   finish_mmap_buf = grub_malloc (finish_mmap_size);
>   if (!finish_mmap_buf)
>     return grub_errno;
>   if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf,
> &finish_key,
>                                &finish_desc_size, &finish_desc_version) <=
> 0)      <== see note 1
>     return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
>   b = grub_efi_system_table->boot_services;
>   status = efi_call_2 (b->exit_boot_services,
> grub_efi_image_handle,    <== see note 2
>                        finish_key);
>   if (status != GRUB_EFI_SUCCESS)
>     return grub_error (GRUB_ERR_IO, "couldn't terminate EFI services");
> 
> Note 1:
> BIOS returns the memory map and the finish_key = X
> 
> Note 2:
> BIOS changes the memory map and the internal finish_key becomes X+1, so the
> input finish_key does not match the interna key, the API call fails.
> 
> ======================================
> 
> 
> Since the BIOS core is from AMI we cannot correct the FW behavior so we did
> a small modification to the GRUB (see below). We retry the exit boot
> service API and this solves the problem.
> Please consider if this modification is reasonable for future grub releases.
> 
> PS. I also checked the latest grub-2.00 code however this part of code is
> the same as grub-1.99, so grub upgrade cannot help.
> 
> 
> do {
>   if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf,
> &finish_key,
>                                &finish_desc_size, &finish_desc_version) < 0)
>     return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
>   if (outbuf && *outbuf_size < finish_mmap_size)
>     return grub_error (GRUB_ERR_IO, "memory map buffer is too small");
>   finish_mmap_buf = grub_malloc (finish_mmap_size);
>   if (!finish_mmap_buf)
>     return grub_errno;
>   if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf,
> &finish_key,
>                                &finish_desc_size, &finish_desc_version) <=
> 0)
>     return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
>   b = grub_efi_system_table->boot_services;
>   status = efi_call_2 (b->exit_boot_services, grub_efi_image_handle,
>                        finish_key);
> 
>   if (status != GRUB_EFI_SUCCESS) {
>     grub_free(finish_mmap_buf);
>   }
> 
> } while (status != GRUB_EFI_SUCCESS && retry++ < 2);  <== retry calling
> exit boot service
> 
> if (status != GRUB_EFI_SUCCESS)
>   return grub_error (GRUB_ERR_IO, "couldn't terminate EFI services");
> 
> 
> 
> Thanks,
> - Weber Wang




reply via email to

[Prev in Thread] Current Thread [Next in Thread]