From: Alexander Jung Date: Mon, 12 Apr 2021 10:42:27 +0000 (+0200) Subject: plat/linuxu: Add initrd memory region X-Git-Tag: RELEASE-0.6~150 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=a1d7129e802a4f1aef3cf086c9aae988821c7bc1;p=unikraft%2Funikraft.git plat/linuxu: Add initrd memory region 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 Signed-off-by: Omar Jamil Signed-off-by: Sachin Beldona Signed-off-by: Gabriel Mocanu Signed-off-by: Alexander Jung Checkpatch-Ignore: INITIALISED_STATIC Reviewed-by: Simon Kuenzer Tested-by: Unikraft CI GitHub-Pull-Request: #179 --- diff --git a/plat/linuxu/include/linuxu/setup.h b/plat/linuxu/include/linuxu/setup.h index 7ed6d7e63..7eea2ee25 100644 --- a/plat/linuxu/include/linuxu/setup.h +++ b/plat/linuxu/include/linuxu/setup.h @@ -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; diff --git a/plat/linuxu/memory.c b/plat/linuxu/memory.c index 5b3df9b3a..5683af264 100644 --- a/plat/linuxu/memory.c +++ b/plat/linuxu/memory.c @@ -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 {