[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