Skip to content

Commit dde6685

Browse files
committed
WIP: Build efivar experiment for Sumit
Signed-off-by: Loïc Minier <[email protected]>
1 parent b01284f commit dde6685

File tree

2 files changed

+334
-0
lines changed

2 files changed

+334
-0
lines changed
Lines changed: 330 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,330 @@
1+
diff -Nru efivar-38/debian/changelog efivar-38/debian/changelog
2+
--- efivar-38/debian/changelog 2024-02-28 02:57:40.000000000 +0000
3+
+++ efivar-38/debian/changelog 2025-05-29 17:32:49.000000000 +0000
4+
@@ -1,3 +1,11 @@
5+
+efivar (38-3.1~invalid1) trixie-noship; urgency=medium
6+
+
7+
+ * Add test patches from https://github.com/rhboot/efivar/pull/267
8+
+ - 0001-efivar-Add-missing-to-usage-help-options.patch
9+
+ - 0002-efivar-Copy-VarToFile-to-RTStorageVolatile-file-at-E.patch
10+
+
11+
+ -- Loïc Minier <[email protected]> Thu, 29 May 2025 17:32:49 +0000
12+
+
13+
efivar (38-3.1) unstable; urgency=medium
14+
15+
* Non-maintainer upload.
16+
diff -Nru efivar-38/debian/patches/0001-efivar-Add-missing-to-usage-help-options.patch efivar-38/debian/patches/0001-efivar-Add-missing-to-usage-help-options.patch
17+
--- efivar-38/debian/patches/0001-efivar-Add-missing-to-usage-help-options.patch 1970-01-01 00:00:00.000000000 +0000
18+
+++ efivar-38/debian/patches/0001-efivar-Add-missing-to-usage-help-options.patch 2025-05-29 17:30:51.000000000 +0000
19+
@@ -0,0 +1,26 @@
20+
+From 249182526c0fd6b7b6d5bc02b96d3376e9051ba9 Mon Sep 17 00:00:00 2001
21+
+From: Javier Tia <[email protected]>
22+
+Date: Sun, 9 Jun 2024 00:12:37 -0600
23+
+Subject: [PATCH 1/2] efivar: Add missing > to usage help options
24+
+
25+
+Signed-off-by: Javier Tia <[email protected]>
26+
+---
27+
+ src/efivar.c | 2 +-
28+
+ 1 file changed, 1 insertion(+), 1 deletion(-)
29+
+
30+
+diff --git a/src/efivar.c b/src/efivar.c
31+
+index 1f9d613..519f7c5 100644
32+
+--- a/src/efivar.c
33+
++++ b/src/efivar.c
34+
+@@ -441,7 +441,7 @@ usage(int ret)
35+
+ " -a, --append append to variable specified by --name\n"
36+
+ " -f, --datafile=<file> load or save variable contents from <file>\n"
37+
+ " -e, --export=<file> export variable to <file>\n"
38+
+- " -i, --import=<file> import variable from <file\n"
39+
++ " -i, --import=<file> import variable from <file>\n"
40+
+ " -L, --list-guids show internal guid list\n"
41+
+ " -w, --write write to variable specified by --name\n\n"
42+
+ "Help options:\n"
43+
+--
44+
+2.47.2
45+
+
46+
diff -Nru efivar-38/debian/patches/0002-efivar-Copy-VarToFile-to-RTStorageVolatile-file-at-E.patch efivar-38/debian/patches/0002-efivar-Copy-VarToFile-to-RTStorageVolatile-file-at-E.patch
47+
--- efivar-38/debian/patches/0002-efivar-Copy-VarToFile-to-RTStorageVolatile-file-at-E.patch 1970-01-01 00:00:00.000000000 +0000
48+
+++ efivar-38/debian/patches/0002-efivar-Copy-VarToFile-to-RTStorageVolatile-file-at-E.patch 2025-05-29 17:30:51.000000000 +0000
49+
@@ -0,0 +1,273 @@
50+
+From 8c7e3610cafd01f57b62c37dbaec2c4ece3fa3c0 Mon Sep 17 00:00:00 2001
51+
+From: Javier Tia <[email protected]>
52+
+Date: Wed, 30 Oct 2024 11:58:53 -0600
53+
+Subject: [PATCH 2/2] efivar: Copy VarToFile to RTStorageVolatile file at ESP
54+
+
55+
+EFI is becoming more common on embedded boards with the embracing of
56+
+SystemReady-IR.
57+
+
58+
+U-Boot which is most commonly used, is usually storing the EFI variables
59+
+in a file in the ESP. That makes it impossible to support SetVariable at
60+
+Runtime reliably, since the OS doesn't know how to access, read or write
61+
+that file.
62+
+
63+
+OS'es usually need SetVariable at runtime for three reasons:
64+
+
65+
+- Set the BootOrder
66+
+- Enable UEFI Secure Boot
67+
+- OSIndication to signal capsule updates on-disk
68+
+
69+
+Since the variables are stored in a file U-Boot enables SetVariable at
70+
+runtime in the EFI config table and stores any updates in RAM. At the
71+
+same file it creates two volatile variables:
72+
+
73+
+- RTStorageVolatile is the location of the file relative to the ESP
74+
+- VarTofile contains a binary dump of the EFI variables that need to be
75+
+ preserved on the file (BS, RT, NV)
76+
+
77+
+U-Boot fills in the VarToFile dynamically on reads and that includes any
78+
+updates the OS did in the meantime.
79+
+
80+
+So, let's update efivar to do the same thing. Once a variable is written
81+
+to the efivarfs, make sure efivars is mounted as rw and scan for the
82+
+file RTStorageVolatile. If we find that, copy the VarToFile contents in
83+
+a file and preserve the variables across reboots.
84+
+
85+
+Suggested-by: Ilias Apalodimas <[email protected]>
86+
+Acked-by: Ilias Apalodimas [email protected]
87+
+Tested-by: Ilias Apalodimas [email protected]
88+
+Signed-off-by: Javier Tia <[email protected]>
89+
+---
90+
+ src/efivarfs.c | 4 ++
91+
+ src/include/efivar/efivar.h | 2 +
92+
+ src/lib.c | 129 ++++++++++++++++++++++++++++++++++++
93+
+ src/libefivar.map.in | 2 +
94+
+ src/vars.c | 8 ++-
95+
+ 5 files changed, 143 insertions(+), 2 deletions(-)
96+
+
97+
+diff --git a/src/efivarfs.c b/src/efivarfs.c
98+
+index 034d6c1..ad2a40f 100644
99+
+--- a/src/efivarfs.c
100+
++++ b/src/efivarfs.c
101+
+@@ -312,6 +312,8 @@ efivarfs_del_variable(efi_guid_t guid, const char *name)
102+
+ if (rc < 0)
103+
+ efi_error("unlink failed");
104+
+
105+
++ efi_save_esp_filename();
106+
++
107+
+ __typeof__(errno) errno_value = errno;
108+
+ free(path);
109+
+ errno = errno_value;
110+
+@@ -442,6 +444,8 @@ efivarfs_set_variable(efi_guid_t guid, const char *name, const uint8_t *data,
111+
+ goto err;
112+
+ }
113+
+
114+
++ efi_save_esp_filename();
115+
++
116+
+ /* we're done */
117+
+ ret = 0;
118+
+
119+
+diff --git a/src/include/efivar/efivar.h b/src/include/efivar/efivar.h
120+
+index b9b265b..a9182b5 100644
121+
+--- a/src/include/efivar/efivar.h
122+
++++ b/src/include/efivar/efivar.h
123+
+@@ -121,6 +121,8 @@ extern int efi_variable_get_attributes(efi_variable_t *var, uint64_t *attrs)
124+
+ extern int efi_variable_realize(efi_variable_t *var)
125+
+ __attribute__((__nonnull__ (1)));
126+
+
127+
++extern void efi_save_esp_filename(void);
128+
++
129+
+ #ifndef EFIVAR_BUILD_ENVIRONMENT
130+
+ extern int efi_error_get(unsigned int n,
131+
+ char ** const filename,
132+
+diff --git a/src/lib.c b/src/lib.c
133+
+index c17a54d..5256320 100644
134+
+--- a/src/lib.c
135+
++++ b/src/lib.c
136+
+@@ -16,6 +16,19 @@
137+
+
138+
+ #include "efivar.h"
139+
+
140+
++#define VAR2FILE "/sys/firmware/efi/efivars/VarToFile-b2ac5fc9-92b7-4acd-aeac-11e818c3130c"
141+
++
142+
++// RTStorageVolatile-b2ac5fc9-92b7-4acd-aeac-11e818c3130c
143+
++#define NAME_RTSV "RTStorageVolatile"
144+
++#define GUID_RTSV \
145+
++ EFI_GUID(0xB2AC5FC9,0x92B7,0x4ACD,0xAEAC,0x11,0xE8,0x18,0xC3,0x13,0x0C)
146+
++
147+
++static const char *esp_paths[] = {
148+
++ "/boot",
149+
++ "/boot/efi",
150+
++ "/efi"
151+
++};
152+
++
153+
+ static int default_probe(void)
154+
+ {
155+
+ return 1;
156+
+@@ -227,6 +240,122 @@ efi_variables_supported(void)
157+
+ return 1;
158+
+ }
159+
+
160+
++static void
161+
++search_esp_filename(const char *filename, char **esp_filename)
162+
++{
163+
++ size_t num_paths = sizeof(esp_paths) / sizeof(esp_paths[0]);
164+
++ size_t esp_filename_size = 0;
165+
++
166+
++ for (size_t i = 0; i < num_paths; ++i) {
167+
++ esp_filename_size = strlen(esp_paths[i]) + strlen(filename) + 2;
168+
++ *esp_filename = malloc(esp_filename_size);
169+
++ if (!*esp_filename) {
170+
++ fprintf(stderr, "Error: Failed to allocate memory for '%s' esp_filename\n", *esp_filename);
171+
++ exit(1);
172+
++ }
173+
++ snprintf(*esp_filename, esp_filename_size, "%s/%s", esp_paths[i], filename);
174+
++
175+
++ struct stat buffer;
176+
++ if (stat(*esp_filename, &buffer) == 0) {
177+
++ return;
178+
++ }
179+
++
180+
++ free(*esp_filename);
181+
++ *esp_filename = NULL;
182+
++ }
183+
++}
184+
++
185+
++static int
186+
++get_esp_filename(char **esp_filename)
187+
++{
188+
++ size_t file_size;
189+
++ uint32_t file_attr;
190+
++ uint8_t *file_data = NULL;
191+
++ int rc = 0;
192+
++
193+
++ rc = efi_get_variable(GUID_RTSV, NAME_RTSV, &file_data, &file_size, &file_attr);
194+
++ if (rc < 0) {
195+
++ // No error print here. The checking should only happen if
196+
++ // RTStorageVolatile is there to begin with. i.e., systems, like x86,
197+
++ // that don't need to store variables in an ESP file
198+
++ return rc;
199+
++ }
200+
++
201+
++ *esp_filename = (char *)file_data;
202+
++
203+
++ return 0;
204+
++}
205+
++
206+
++static void
207+
++save_esp_filename(const char *esp_filename) {
208+
++ FILE *var2file = NULL;
209+
++ FILE *output_file = NULL;
210+
++ unsigned char buffer[1024];
211+
++ size_t bytes_read, bytes_written;
212+
++ bool fail = false;
213+
++
214+
++ var2file = fopen(VAR2FILE, "rb");
215+
++ if (!var2file) {
216+
++ fprintf(stderr, "Error: Could not open file '%s'\n", VAR2FILE);
217+
++ exit(1);
218+
++ }
219+
++
220+
++ output_file = fopen(esp_filename, "wb");
221+
++ if (!output_file) {
222+
++ fprintf(stderr, "Error: Could not open file '%s'\n", esp_filename);
223+
++ fclose(var2file);
224+
++ exit(1);
225+
++ }
226+
++
227+
++ if (fread(buffer, 1, 4, var2file) < 4) {
228+
++ fprintf(stderr, "Error: Could not skip first 4 bytes or '%s' file is too small\n", esp_filename);
229+
++ fail = true;
230+
++ goto clean;
231+
++ }
232+
++
233+
++ while ((bytes_read = fread(buffer, 1, sizeof(buffer), var2file)) > 0) {
234+
++ bytes_written = fwrite(buffer, 1, bytes_read, output_file);
235+
++ if (bytes_written != bytes_read) {
236+
++ fprintf(stderr, "Error: Could not write data to ESP '%s' file\n", esp_filename);
237+
++ fail = true;
238+
++ goto clean;
239+
++ }
240+
++ }
241+
++
242+
++clean:
243+
++ fclose(var2file);
244+
++ fclose(output_file);
245+
++
246+
++ if (fail)
247+
++ exit(1);
248+
++}
249+
++
250+
++void PUBLIC
251+
++efi_save_esp_filename(void)
252+
++{
253+
++ int rc = 0;
254+
++ char *esp_filename = NULL;
255+
++ char *esp_filename_path = NULL;
256+
++
257+
++ rc = get_esp_filename(&esp_filename);
258+
++ if (rc < 0 || !esp_filename) {
259+
++ goto cleanup;
260+
++ }
261+
++
262+
++ search_esp_filename(esp_filename, &esp_filename_path);
263+
++ if (esp_filename_path) {
264+
++ save_esp_filename(esp_filename_path);
265+
++ }
266+
++ else {
267+
++ fprintf(stderr, "Error: no ESP '%s' file found in ESP partitions to save VarToFile\n", esp_filename);
268+
++ goto cleanup;
269+
++ }
270+
++
271+
++cleanup:
272+
++ free(esp_filename);
273+
++ free(esp_filename_path);
274+
++}
275+
++
276+
+ static void CONSTRUCTOR libefivar_init(void);
277+
+
278+
+ static void CONSTRUCTOR
279+
+diff --git a/src/libefivar.map.in b/src/libefivar.map.in
280+
+index 59f1a72..fa94d6d 100644
281+
+--- a/src/libefivar.map.in
282+
++++ b/src/libefivar.map.in
283+
+@@ -90,6 +90,8 @@ libefivar.so.0 {
284+
+ efi_guid_x509_sha384;
285+
+ efi_guid_x509_sha512;
286+
+ efi_guid_zero;
287+
++
288+
++ efi_save_esp_filename;
289+
+ local: *;
290+
+ };
291+
+
292+
+diff --git a/src/vars.c b/src/vars.c
293+
+index 1cd23d2..81bedb1 100644
294+
+--- a/src/vars.c
295+
++++ b/src/vars.c
296+
+@@ -435,8 +435,10 @@ vars_del_variable(efi_guid_t guid, const char *name)
297+
+ }
298+
+
299+
+ rc = write(fd, buf, buf_size);
300+
+- if (rc >= 0)
301+
++ if (rc >= 0) {
302+
++ efi_save_esp_filename();
303+
+ ret = 0;
304+
++ }
305+
+ else
306+
+ efi_error("write() failed");
307+
+ err:
308+
+@@ -594,8 +596,10 @@ vars_set_variable(efi_guid_t guid, const char *name, const uint8_t *data,
309+
+ rc = write(fd, &var32, sizeof(var32));
310+
+ }
311+
+
312+
+- if (rc >= 0)
313+
++ if (rc >= 0) {
314+
++ efi_save_esp_filename();
315+
+ ret = 0;
316+
++ }
317+
+ else
318+
+ efi_error("write() failed");
319+
+
320+
+--
321+
+2.47.2
322+
+
323+
diff -Nru efivar-38/debian/patches/series efivar-38/debian/patches/series
324+
--- efivar-38/debian/patches/series 2023-11-29 14:23:32.000000000 +0000
325+
+++ efivar-38/debian/patches/series 2025-05-29 17:32:37.000000000 +0000
326+
@@ -1,2 +1,4 @@
327+
0001-linux-handle-non-ACPI-systems-in-device_get.patch
328+
0002_no_host_march.patch
329+
+0001-efivar-Add-missing-to-usage-help-options.patch
330+
+0002-efivar-Copy-VarToFile-to-RTStorageVolatile-file-at-E.patch
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
dsc_url: "https://snapshot.debian.org/archive/debian/20240229T041529Z/pool/main/e/efivar/efivar_38-3.1.dsc"
2+
dsc_sha256sum: "8cb5bc65ed548f5c223935a5d7396e4c67430096d318e7263b5cb2ffe771629e"
3+
debdiff_file: "efivar_38-3.1~invalid1.debdiff"
4+
suite: "trixie"

0 commit comments

Comments
 (0)