]> xenbits.xensource.com Git - unikraft/unikraft.git/commitdiff
plat/linuxu: Add initrd memory region
authorAlexander Jung <a.jung@lancs.ac.uk>
Mon, 12 Apr 2021 10:42:27 +0000 (12:42 +0200)
committerUnikraft <monkey@unikraft.io>
Mon, 5 Jul 2021 04:47:27 +0000 (04:47 +0000)
Add a new library parameter (initrd_file). The parameter can be used to
map a file on the host filesystem to to a new memory region on boot.

Signed-off-by: Robert Hrusecky <roberth@cs.utexas.edu>
Signed-off-by: Omar Jamil <omarj2898@gmail.com>
Signed-off-by: Sachin Beldona <sachinbeldona@utexas.edu>
Signed-off-by: Gabriel Mocanu <gabi.mocanu98@gmail.com>
Signed-off-by: Alexander Jung <a.jung@lancs.ac.uk>
Checkpatch-Ignore: INITIALISED_STATIC
Reviewed-by: Simon Kuenzer <simon.kuenzer@neclab.eu>
Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Pull-Request: #179

plat/linuxu/include/linuxu/setup.h
plat/linuxu/memory.c

index 7ed6d7e637a6b14ea51a3208a069da2722c15078..7eea2ee2513cc1737d65ea4f6b56f9574b559864 100644 (file)
@@ -44,10 +44,6 @@ struct liblinuxuplat_memregion {
 struct liblinuxuplat_opts {
        struct liblinuxuplat_memregion heap;
        struct liblinuxuplat_memregion initrd;
-       struct {
-               void *base;
-               size_t len;
-       } heap;
 };
 
 extern struct liblinuxuplat_opts _liblinuxuplat_opts;
index 5b3df9b3acda938470381b835cceb36f4ace5b5f..5683af26419b673ea14038b4cb0f62919eca401d 100644 (file)
@@ -45,6 +45,9 @@
 static __u32 heap_size = CONFIG_LINUXU_DEFAULT_HEAPMB;
 UK_LIB_PARAM(heap_size, __u32);
 
+static const char *initrd;
+UK_LIB_PARAM_STR(initrd);
+
 static int __linuxu_plat_heap_init(void)
 {
        void *pret;
@@ -70,23 +73,80 @@ static int __linuxu_plat_heap_init(void)
 
 }
 
+static int __linuxu_plat_initrd_init(void)
+{
+       void *pret;
+       int rc = 0;
+       struct k_stat file_info;
+
+       if (initrd == NULL) {
+               uk_pr_debug("No initrd present.\n");
+       } else {
+               uk_pr_debug("Mapping in initrd file: %s\n", initrd);
+               int initrd_fd = sys_open(initrd, K_O_RDONLY, 0);
+
+               if (initrd_fd < 0) {
+                       uk_pr_crit("Failed to open %s for initrd\n", initrd);
+                       return -1;
+               }
+
+               /**
+                * Find initrd file size
+                */
+               if (sys_fstat(initrd_fd, &file_info) < 0) {
+                       uk_pr_crit("sys_fstat failed for initrd file\n");
+                       sys_close(initrd_fd);
+                       return -1;
+               }
+               _liblinuxuplat_opts.initrd.len = file_info.st_size;
+               /**
+                * Allocate initrd memory
+                */
+               if (_liblinuxuplat_opts.initrd.len > 0) {
+                       pret = sys_mmap(NULL,
+                                       _liblinuxuplat_opts.initrd.len,
+                                       PROT_READ | PROT_WRITE | PROT_EXEC,
+                                       MAP_PRIVATE, initrd_fd, 0);
+                       if (PTRISERR(pret)) {
+                               rc = PTR2ERR(pret);
+                               uk_pr_crit("Failed to memory-map initrd: %d\n",
+                                          rc);
+                               sys_close(initrd_fd);
+                               return -1;
+                       }
+                       _liblinuxuplat_opts.initrd.base = pret;
+               } else {
+                       uk_pr_info("Ignoring empty initrd file.\n");
+                       sys_close(initrd_fd);
+                       return 0;
+               }
+       }
+       return rc;
+}
+
 int ukplat_memregion_count(void)
 {
        static int have_heap = 0;
+       static int have_initrd = 0;
        int rc = 0;
 
+       /*
+        * NOTE: The heap size and initrd file can be changed by a
+        * library parameter. We assume that those ones are processed
+        * by the boot library shortly before memory regions are
+        * scanned. This is why we initialize the heap here.
+        */
        if (!have_heap) {
-               /*
-                * NOTE: The heap size can be changed by a library parameter.
-                * We assume that those ones are processed by the boot library
-                * shortly before memory regions are scanned. This is why
-                * we initialize the heap here.
-                */
                rc = __linuxu_plat_heap_init();
                have_heap = (rc == 0) ? 1 : 0;
        }
 
-       return (have_heap) ? 1 : 0;
+       if (!have_initrd) {
+               rc = __linuxu_plat_initrd_init();
+               have_initrd = (rc == 0) ? 1 : 0;
+       }
+
+       return have_heap + have_initrd;
 }
 
 int ukplat_memregion_get(int i, struct ukplat_memregion_desc *m)
@@ -101,6 +161,17 @@ int ukplat_memregion_get(int i, struct ukplat_memregion_desc *m)
                m->flags = UKPLAT_MEMRF_ALLOCATABLE;
 #if CONFIG_UKPLAT_MEMRNAME
                m->name  = "heap";
+#endif
+               ret = 0;
+       } else if ((i == 0 && !_liblinuxuplat_opts.heap.base
+                               && _liblinuxuplat_opts.initrd.base)
+                               || (i == 1 && _liblinuxuplat_opts.heap.base
+                                       && _liblinuxuplat_opts.initrd.base)) {
+               m->base = _liblinuxuplat_opts.initrd.base;
+               m->len = _liblinuxuplat_opts.initrd.len;
+               m->flags = UKPLAT_MEMRF_INITRD | UKPLAT_MEMRF_WRITABLE;
+#if CONFIG_UKPLAT_MEMRNAME
+               m->name = "initrd";
 #endif
                ret = 0;
        } else {