aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Percival <cperciva@FreeBSD.org>2021-05-30 20:17:11 +0000
committerColin Percival <cperciva@FreeBSD.org>2021-06-21 03:09:41 +0000
commit60a978bec9123fcb9c74bd925e06dd3f4faddac6 (patch)
tree0722104aa6e08c90b111240176d2ef4c2d0ccd8b
parent4afa62be71674b76c31ea513d6c470089a6c1848 (diff)
downloadsrc-60a978bec9123fcb9c74bd925e06dd3f4faddac6.tar.gz
src-60a978bec9123fcb9c74bd925e06dd3f4faddac6.zip
stand/common: Add file_addbuf()
This provides an interface for a memory buffer to be passed from the loader to the kernel as a "preloaded module". Reviewed by: kevans
-rw-r--r--stand/common/bootstrap.h1
-rw-r--r--stand/common/module.c51
2 files changed, 52 insertions, 0 deletions
diff --git a/stand/common/bootstrap.h b/stand/common/bootstrap.h
index f671dba96e63..d94d35b555e4 100644
--- a/stand/common/bootstrap.h
+++ b/stand/common/bootstrap.h
@@ -260,6 +260,7 @@ void file_addmetadata(struct preloaded_file *, int, size_t, void *);
int file_addmodule(struct preloaded_file *, char *, int,
struct kernel_module **);
void file_removemetadata(struct preloaded_file *fp);
+int file_addbuf(const char *name, const char *type, size_t len, void *buf);
vm_offset_t build_font_module(vm_offset_t);
diff --git a/stand/common/module.c b/stand/common/module.c
index 34ffc10cded3..8bddd9f56f52 100644
--- a/stand/common/module.c
+++ b/stand/common/module.c
@@ -1042,6 +1042,57 @@ file_removemetadata(struct preloaded_file *fp)
fp->f_metadata = NULL;
}
+/*
+ * Add a buffer to the list of preloaded "files".
+ */
+int
+file_addbuf(const char *name, const char *type, size_t len, void *buf)
+{
+ struct preloaded_file *fp;
+ vm_offset_t dest;
+
+ /* We can't load first */
+ if ((file_findfile(NULL, NULL)) == NULL) {
+ command_errmsg = "can't load file before kernel";
+ return (-1);
+ }
+
+ /* Figure out where to load the data. */
+ dest = loadaddr;
+ if (archsw.arch_loadaddr != NULL)
+ dest = archsw.arch_loadaddr(LOAD_RAW, (void *)name, dest);
+
+ /* Create & populate control structure */
+ fp = file_alloc();
+ if (fp == NULL) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "no memory to load %s", name);
+ return (-1);
+ }
+ fp->f_name = strdup(name);
+ fp->f_type = strdup(type);
+ fp->f_args = NULL;
+ fp->f_metadata = NULL;
+ fp->f_loader = -1;
+ fp->f_addr = dest;
+ fp->f_size = len;
+ if ((fp->f_name == NULL) || (fp->f_type == NULL)) {
+ snprintf(command_errbuf, sizeof (command_errbuf),
+ "no memory to load %s", name);
+ free(fp->f_name);
+ free(fp->f_type);
+ return (-1);
+ }
+
+ /* Copy the data in. */
+ archsw.arch_copyin(buf, fp->f_addr, len);
+ loadaddr = fp->f_addr + len;
+
+ /* Add to the list of loaded files */
+ file_insert_tail(fp);
+ return(0);
+}
+
struct file_metadata *
metadata_next(struct file_metadata *md, int type)
{