[PATCH 05/16] fs: efivarfs: prepare for use with barebox as EFI loader
Ahmad Fatoum
a.fatoum at pengutronix.de
Thu Dec 11 12:29:56 PST 2025
The barebox efivarfs is currently only registered when barebox is an EFI
payload. It hardcodes use of RT to access the runtime services and the
efivarfs is mounted on every startup.
Replace this with an automount and rework the file system slightly, so
the file system can be mounted later outside of payload once barebox
activates the upcoming EFI loader support.
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
common/startup.c | 4 ++--
efi/efivar.c | 1 +
fs/Kconfig | 2 +-
fs/efivarfs.c | 38 ++++++++++++++++++++++++++++----------
4 files changed, 32 insertions(+), 13 deletions(-)
diff --git a/common/startup.c b/common/startup.c
index 602233345a25..c48adb42f953 100644
--- a/common/startup.c
+++ b/common/startup.c
@@ -62,9 +62,9 @@ static int mount_root(void)
mkdir("/mnt", 0);
devfs_init();
- if (IS_ENABLED(CONFIG_FS_EFIVARFS) && efi_is_payload()) {
+ if (IS_ENABLED(CONFIG_FS_EFIVARFS)) {
mkdir("/efivars", 0);
- mount("none", "efivarfs", "/efivars", NULL);
+ automount_add("/efivars", "mount -t efivarfs none /efivars");
}
if (IS_ENABLED(CONFIG_FS_PSTORE)) {
diff --git a/efi/efivar.c b/efi/efivar.c
index a51f3b2d1d8e..808693a7a746 100644
--- a/efi/efivar.c
+++ b/efi/efivar.c
@@ -14,6 +14,7 @@
#include <efi/variable.h>
#include <wchar.h>
#include <xfuncs.h>
+#include <errno.h>
#include <linux/sprintf.h>
void *efi_get_variable(char *name, efi_guid_t *vendor, int *var_size)
diff --git a/fs/Kconfig b/fs/Kconfig
index e86420f9c259..c0c634bb419d 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -94,7 +94,7 @@ config FS_EFI
by the EFI Firmware via the EFI Simple File System Protocol.
config FS_EFIVARFS
- depends on EFI_PAYLOAD
+ depends on EFI
select FS_LEGACY
select FS_WRITABLE
bool
diff --git a/fs/efivarfs.c b/fs/efivarfs.c
index 7b80e703f2d9..3641dd92917d 100644
--- a/fs/efivarfs.c
+++ b/fs/efivarfs.c
@@ -25,6 +25,7 @@
#include <xfuncs.h>
#include <fcntl.h>
#include <efi.h>
+#include <efi/efi-mode.h>
#include <wchar.h>
#include <linux/err.h>
#include <linux/ctype.h>
@@ -45,12 +46,14 @@ struct efivarfs_dir {
struct efivarfs_priv {
struct list_head inodes;
+ struct efi_runtime_services *rt;
};
static int efivars_create(struct device *dev, const char *pathname,
mode_t mode)
{
struct efivarfs_priv *priv = dev->priv;
+ struct efi_runtime_services *rt = priv->rt;
struct efivarfs_inode *inode;
efi_guid_t vendor;
efi_status_t efiret;
@@ -79,7 +82,7 @@ static int efivars_create(struct device *dev, const char *pathname,
inode->full_name = basprintf("%s-%pUl", name8, &inode->vendor);
free(name8);
- efiret = RT->set_variable(inode->name, &inode->vendor,
+ efiret = rt->set_variable(inode->name, &inode->vendor,
EFI_VARIABLE_NON_VOLATILE |
EFI_VARIABLE_BOOTSERVICE_ACCESS |
EFI_VARIABLE_RUNTIME_ACCESS,
@@ -97,6 +100,7 @@ static int efivars_create(struct device *dev, const char *pathname,
static int efivars_unlink(struct device *dev, const char *pathname)
{
struct efivarfs_priv *priv = dev->priv;
+ struct efi_runtime_services *rt = priv->rt;
struct efivarfs_inode *inode, *tmp;
efi_status_t efiret;
@@ -105,7 +109,7 @@ static int efivars_unlink(struct device *dev, const char *pathname)
list_for_each_entry_safe(inode, tmp, &priv->inodes, node) {
if (!strcmp(inode->full_name, pathname)) {
- efiret = RT->set_variable(inode->name, &inode->vendor,
+ efiret = rt->set_variable(inode->name, &inode->vendor,
0, 0, NULL);
if (EFI_ERROR(efiret))
return -efi_errno(efiret);
@@ -123,10 +127,13 @@ struct efivars_file {
efi_guid_t vendor;
s16 *name;
u32 attributes;
+ struct efivarfs_priv *priv;
};
static int efivarfs_open(struct device *dev, struct file *f, const char *filename)
{
+ struct efivarfs_priv *priv = dev->priv;
+ struct efi_runtime_services *rt = priv->rt;
struct efivars_file *efile;
efi_status_t efiret;
int ret;
@@ -137,7 +144,7 @@ static int efivarfs_open(struct device *dev, struct file *f, const char *filenam
if (ret)
return -ENOENT;
- efiret = RT->get_variable(efile->name, &efile->vendor,
+ efiret = rt->get_variable(efile->name, &efile->vendor,
NULL, &efile->size, NULL);
if (EFI_ERROR(efiret) && efiret != EFI_BUFFER_TOO_SMALL) {
ret = -efi_errno(efiret);
@@ -150,7 +157,7 @@ static int efivarfs_open(struct device *dev, struct file *f, const char *filenam
goto out;
}
- efiret = RT->get_variable(efile->name, &efile->vendor,
+ efiret = rt->get_variable(efile->name, &efile->vendor,
&efile->attributes, &efile->size,
efile->buf);
if (EFI_ERROR(efiret)) {
@@ -158,6 +165,8 @@ static int efivarfs_open(struct device *dev, struct file *f, const char *filenam
goto out;
}
+ efile->priv = priv;
+
f->f_size = efile->size;
f->private_data = efile;
@@ -192,6 +201,7 @@ static int efivarfs_read(struct file *f, void *buf, size_t insize)
static int efivarfs_write(struct file *f, const void *buf, size_t insize)
{
struct efivars_file *efile = f->private_data;
+ struct efi_runtime_services *rt = efile->priv->rt;
efi_status_t efiret;
if (efile->size < f->f_pos + insize) {
@@ -201,7 +211,7 @@ static int efivarfs_write(struct file *f, const void *buf, size_t insize)
memcpy(efile->buf + f->f_pos, buf, insize);
- efiret = RT->set_variable(efile->name, &efile->vendor,
+ efiret = rt->set_variable(efile->name, &efile->vendor,
efile->attributes,
efile->size ? efile->size : 1, efile->buf);
if (EFI_ERROR(efiret))
@@ -213,12 +223,13 @@ static int efivarfs_write(struct file *f, const void *buf, size_t insize)
static int efivarfs_truncate(struct file *f, loff_t size)
{
struct efivars_file *efile = f->private_data;
+ struct efi_runtime_services *rt = efile->priv->rt;
efi_status_t efiret;
efile->size = size;
efile->buf = realloc(efile->buf, efile->size + sizeof(uint32_t));
- efiret = RT->set_variable(efile->name, &efile->vendor,
+ efiret = rt->set_variable(efile->name, &efile->vendor,
efile->attributes,
efile->size ? efile->size : 1, efile->buf);
if (EFI_ERROR(efiret))
@@ -268,6 +279,8 @@ static int efivarfs_closedir(struct device *dev, DIR *dir)
static int efivarfs_stat(struct device *dev, const char *filename,
struct stat *s)
{
+ struct efivarfs_priv *priv = dev->priv;
+ struct efi_runtime_services *rt = priv->rt;
efi_guid_t vendor;
s16 *name;
efi_status_t efiret;
@@ -278,7 +291,7 @@ static int efivarfs_stat(struct device *dev, const char *filename,
if (ret)
return -ENOENT;
- efiret = RT->get_variable(name, &vendor, NULL, &size, NULL);
+ efiret = rt->get_variable(name, &vendor, NULL, &size, NULL);
free(name);
@@ -299,17 +312,23 @@ static int efivarfs_probe(struct device *dev)
char *name8;
size_t size;
struct efivarfs_priv *priv;
+ struct efi_runtime_services *rt;
+
+ rt = efi_get_runtime_services();
+ if (!rt)
+ return -ENODEV;
name[0] = 0;
priv = xzalloc(sizeof(*priv));
+ priv->rt = rt;
INIT_LIST_HEAD(&priv->inodes);
while (1) {
struct efivarfs_inode *inode;
size = sizeof(name);
- efiret = RT->get_next_variable(&size, name, &vendor);
+ efiret = rt->get_next_variable(&size, name, &vendor);
if (EFI_ERROR(efiret))
break;
@@ -370,5 +389,4 @@ static int efivarfs_init(void)
{
return register_fs_driver(&efivarfs_driver);
}
-
-coredevice_efi_initcall(efivarfs_init);
+coredevice_initcall(efivarfs_init);
--
2.47.3
More information about the barebox
mailing list