We have been experimenting with measured launch of environments other than 
Linux and Xen, such as the RTS hypervisor and some real-time operating systems. 

We have seen a recurring issue in some cases with the way TBoot launches 
multiboot/multiboot2 environments. Namely, when loading the ELF image, TBoot 
overwrites the kernel ELF image and modules.

Developers at RTS have made changes to "tboot/common/loader.c" and 
"tboot/common/elf.c" that addresses this issue:
When the follow-on kernel is a multiboot or multiboot2 kernel, move the modules 
to the top of memory as reported in the E820 map. Then, after loading the 
kernel ELF binary into its final location in memory, move the modules to a 
location just above the kernel.

The patches for these changes are below.

thanks,

Safayet

Signed-off-by: Raphael Baum  <r.b...@real-time-systems.com>
Signed-off-by: Safayet Ahmed <safayet.ah...@ge.com>

diff -r 6531a0eaf369 tboot/common/elf.c
--- a/tboot/common/elf.c    Wed May 18 10:13:24 2016 -0700
+++ b/tboot/common/elf.c    Mon Jun 13 10:19:02 2016 -0400
@@ -146,7 +146,5 @@
 }
 
-#if 0
-static bool get_elf_image_range(const elf_header_t *elf, void **start,
-                                void **end)
+bool get_elf_image_range(const elf_header_t *elf, void **start, void **end)
 {
     uint32_t u_start, u_end;
@@ -189,5 +187,4 @@
     }
 }
-#endif
 
 bool expand_elf_image(const void *image, void **entry_point)
diff -r 6531a0eaf369 tboot/common/loader.c
--- a/tboot/common/loader.c    Wed May 18 10:13:24 2016 -0700
+++ b/tboot/common/loader.c    Mon Jun 13 10:19:02 2016 -0400
@@ -4,4 +4,5 @@
  *
  * Copyright (c) 2006-2013, Intel Corporation
+ * Copyright (c) 2016 Real-Time Systems GmbH
  * All rights reserved.
  *
@@ -65,5 +66,5 @@
 /* multiboot struct saved so that post_launch() can use it (in tboot.c) */
 extern loader_ctx *g_ldr_ctx;
-
+extern bool get_elf_image_range(const elf_header_t *elf, void **start, void 
**end);
 extern bool is_elf_image(const void *image, size_t size);
 extern bool expand_elf_image(const elf_header_t *elf, void **entry_point);
@@ -770,4 +771,96 @@
 }
 
+/*
+ * Move all mbi components/modules/mbi to end of memory
+ */
+static bool move_modules_to_high_memory(loader_ctx *lctx)
+{
+    uint64_t max_ram_base = 0,
+             max_ram_size = 0;
+    uint32_t memRequired = 0;
+
+    uint32_t module_count = get_module_count(lctx);
+
+    for ( unsigned int i = 0; i < module_count; i++ )
+    {
+        module_t *m = get_module(lctx,i);
+        memRequired += PAGE_UP(m->mod_end - m->mod_start);
+    }
+
+    get_highest_sized_ram(memRequired, 0x100000000ULL, &max_ram_base, 
&max_ram_size);
+    if(!max_ram_base || !max_ram_size)
+    {
+        printk(TBOOT_INFO"ERROR No suitable memory area found for image 
relocation!\n");
+    printk(TBOOT_INFO"required 0x%X\n", memRequired);
+        return false;
+    }
+
+    printk(TBOOT_INFO"highest suitable area @ 0x%llX (size 0x%llX)\n", 
max_ram_base, max_ram_size);
+
+    unsigned long target_addr =  PAGE_DOWN(max_ram_base + max_ram_size);
+
+    for ( unsigned int i = 0; i < module_count; i++ )
+    {
+        unsigned long base, size;
+        module_t *m = get_module(lctx,i);
+        base = m->mod_start;
+        size = m->mod_end - m->mod_start;
+        printk(TBOOT_INFO"moving module %u (%lu bytes) from 0x%08X ", i, size, 
(uint32_t)base);
+
+        //calculate target addresses
+        target_addr = PAGE_DOWN(target_addr - size);
+        printk(TBOOT_INFO"to 0x%08X\n", (uint32_t)target_addr);
+
+        memcpy((void *)target_addr, (void *)base, size);
+        m->mod_start = target_addr;
+        m->mod_end = target_addr + size;
+    }
+
+    return true;
+}
+
+/*
+ * Move any mbi components/modules/mbi that just above the kernel
+ */
+static bool move_modules_above_elf_kernel(loader_ctx *lctx, elf_header_t 
*kernel_image)
+{
+    if (LOADER_CTX_BAD(lctx))
+        return false;
+
+    /* get end address of loaded elf image */
+    void *elf_start=NULL, *elf_end=NULL;
+    if ( !get_elf_image_range(kernel_image, &elf_start, &elf_end) )
+    {
+        printk(TBOOT_INFO"ERROR: failed tget elf image range\n");
+    }
+
+    printk(TBOOT_INFO"ELF kernel top is at 0x%X\n", (uint32_t)elf_end);
+
+    /* keep modules page aligned */
+    uint32_t target_addr = PAGE_UP((uint32_t)elf_end);
+
+    uint32_t module_count = get_module_count(lctx);
+
+    for ( unsigned int i = 0; i < module_count; i++ )
+    {
+        unsigned long base, size;
+        module_t *m = get_module(lctx,i);
+        base = m->mod_start;
+        size = m->mod_end - m->mod_start;
+        printk(TBOOT_INFO"moving module %u (%lu bytes) from 0x%08X ", i, size, 
(uint32_t)base);
+
+        //calculate target addresses
+        printk(TBOOT_INFO"to 0x%08X\n", (uint32_t)target_addr);
+
+        memcpy((void *)target_addr, (void *)base, size);
+        m->mod_start = target_addr;
+        m->mod_end = target_addr + size;
+
+        target_addr = PAGE_UP(target_addr + size);
+    }
+
+    return true;
+}
+
 static void fixup_modules(loader_ctx *lctx, size_t offset)
 {
@@ -1245,4 +1338,9 @@
         /* fix for GRUB2, which may load modules into memory before tboot */
         move_modules(g_ldr_ctx);
+
+        /* move modules out of the way (to top og memory below 4G) */
+        printk(TBOOT_INFO"move modules to high memory\n");
+        if(!move_modules_to_high_memory(g_ldr_ctx))
+            return false;
     }
     else {
@@ -1263,4 +1361,9 @@
                                &kernel_entry_point) )
             return false;
+
+        /* move modules on top of expanded kernel */
+        if(!move_modules_above_elf_kernel(g_ldr_ctx, (elf_header_t 
*)kernel_image))
+            return false;
+
         printk(TBOOT_INFO"transfering control to kernel @%p...\n", 
                kernel_entry_point);

------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are 
consuming the most bandwidth. Provides multi-vendor support for NetFlow, 
J-Flow, sFlow and other flows. Make informed decisions using capacity 
planning reports. https://ad.doubleclick.net/ddm/clk/305295220;132659582;e
_______________________________________________
tboot-devel mailing list
tboot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tboot-devel

Reply via email to