From: khaalid <khaliidca...@gmail.com>

This RFC patch introduces a UEFI error message printer that translates 
UEFI status codes from hexadecimal values into human-readable strings.

The idea is inspired by the GNU C Library's "perror()" function, which 
translates 
"errno" values into descriptive error messages. Similarly, this implementation 
eliminates 
the need for conditional statements when printing UEFI error messages. In 
short, it's a "perror"-like 
mechanism tailored for UEFI status codes in GRUB.

During development, I encountered a few limitations that led me to believe this 
approach
is the most practical. The biggest one is the difference between GRUB error 
codes (enum "grub_err_t") and
UEFI status codes, they represent different contexts, so we likely need to 
account for them separately.

The function takes three parameters:
 - "grub_err_t": for setting GRUB's errno if desired.
 - "const char *string": a custom message to describe the error context.
 - "EFI_STATUS": the UEFI status code to be translated into a string. Since we 
don't have a global variable 
   for UEFI status codes (like glibc has for "errno"), we pass it directly.

Right now, I've left out features like translations (i18n). I'm open to 
feedback on whether 
that's worth adding at this stage.

Lastly, if this patch is accepted, it might be valuable to propagate it 
throughout the UEFI subsystem. 
That would mean replacing some calls to "grub_error()" with this function, as 
this new function internally 
calls "grub_error()" too. The benefit would be clearer, more descriptive error 
messages 
instead of raw hex codes, which improves both user experience and debugging 
clarity.

Looking forward to your thoughts and feedback.

Best regards,  
Khaalid

Signed-off-by: Khalid Ali <khaliidca...@gmail.com>
---
 grub-core/kern/efi/err.c | 81 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 81 insertions(+)
 create mode 100644 grub-core/kern/efi/err.c

diff --git a/grub-core/kern/efi/err.c b/grub-core/kern/efi/err.c
new file mode 100644
index 000000000..b870b26ba
--- /dev/null
+++ b/grub-core/kern/efi/err.c
@@ -0,0 +1,81 @@
+/* err.c - uefi specific error handling routine */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2025 Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/err.h>
+#include <grub/misc.h>
+#include <grub/efi/api.h>
+#include <grub/efi/efi.h>
+
+struct grub_efi_err
+{
+    grub_efi_status_t status;
+    const char *error_msg;
+};
+
+/* EFI error table: keep entries sorted alphabetically. */
+static const struct grub_efi_err grub_efi_err_table[] = 
+{
+    {GRUB_EFI_ABORTED, "aborted"},
+    {GRUB_EFI_ACCESS_DENIED, "access denied"},
+    {GRUB_EFI_ALREADY_STARTED, "already started"},
+    {GRUB_EFI_BAD_BUFFER_SIZE, "bad buffer size"},
+    {GRUB_EFI_BUFFER_TOO_SMALL, "buffer too small"},
+    {GRUB_EFI_CRC_ERROR, "crc error"},
+    {GRUB_EFI_DEVICE_ERROR, "device error"},
+    {GRUB_EFI_END_OF_FILE, "end of file"},
+    {GRUB_EFI_END_OF_MEDIA, "end of media"},
+    {GRUB_EFI_HTTP_ERROR, "http error"},
+    {GRUB_EFI_ICMP_ERROR, "icmp error"},
+    {GRUB_EFI_INCOMPATIBLE_VERSION, "incompatible version"},
+    {GRUB_EFI_INVALID_PARAMETER, "invalid parameter"},
+    {GRUB_EFI_IP_ADDRESS_CONFLICT, "ip address conflict"},
+    {GRUB_EFI_LOAD_ERROR, "load error"},
+    {GRUB_EFI_MEDIA_CHANGED, "media changed"},
+    {GRUB_EFI_NO_MAPPING, "no mapping"},
+    {GRUB_EFI_NO_MEDIA, "no media"},
+    {GRUB_EFI_NO_RESPONSE, "no response"},
+    {GRUB_EFI_NOT_FOUND, "not found"},
+    {GRUB_EFI_NOT_READY, "not ready"},
+    {GRUB_EFI_NOT_STARTED, "not started"},
+    {GRUB_EFI_OUT_OF_RESOURCES, "out of resources"},
+    {GRUB_EFI_PROTOCOL_ERROR, "protocol error"},
+    {GRUB_EFI_SECURITY_VIOLATION, "security violation"},
+    {GRUB_EFI_SUCCESS, "success"},
+    {GRUB_EFI_TFTP_ERROR, "tftp error"},
+    {GRUB_EFI_TIMEOUT, "timed out"},
+    {GRUB_EFI_UNSPECIFIED_TIMEZONE, "unspecified timezone"},
+    {GRUB_EFI_UNSUPPORTED, "unsupported"},
+    {GRUB_EFI_VOLUME_CORRUPTED, "volume corrupted"},
+    {GRUB_EFI_VOLUME_FULL, "volume full"},
+    {GRUB_EFI_WRITE_PROTECTED, "write protected"}
+};
+
+void
+grub_efi_perror(grub_err_t err, const char *s, grub_efi_status_t status)
+{
+    for (grub_size_t i = 0; i < ARRAY_SIZE(grub_efi_err_table); i++) 
+    {
+        if (grub_efi_err_table[i].status == status)
+        {
+            grub_error (err, "%s : %s", s, grub_efi_err_table[i].error_msg);
+            return; /* we got what we needed, that is enough*/
+        } 
+    }
+    grub_error (err, "%s : unknown error", s);
+}
\ No newline at end of file
-- 
2.49.0


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to