[syslinux:firmware] tests: unit test bios_boot_linux()

syslinux-bot for Matt Fleming matt.fleming at intel.com
Fri Jul 26 07:21:05 PDT 2013


Commit-ID:  e4fd80fb096858c399b17c308986aaed563b8ca9
Gitweb:     http://www.syslinux.org/commit/e4fd80fb096858c399b17c308986aaed563b8ca9
Author:     Matt Fleming <matt.fleming at intel.com>
AuthorDate: Fri, 26 Jul 2013 10:27:57 +0100
Committer:  Matt Fleming <matt.fleming at intel.com>
CommitDate: Fri, 26 Jul 2013 10:39:01 +0100

tests: unit test bios_boot_linux()

The constraints for allocating the kernel cmdline buffer under bios are
pretty involved and filled with historic rules. Unit test the bios linux
loader to ensure we never violate any of them, while at the same time
making sure we actually find a usable chunk of memory.

This commit is designed to test the changes in commit 77cadda8
("load_linux: dynamically calculate the cmdline region").

Signed-off-by: Matt Fleming <matt.fleming at intel.com>

---
 com32/lib/syslinux/tests/Makefile          |   3 +-
 com32/lib/syslinux/tests/load_linux.c      | 199 +++++++++++++++++++++++++++++
 tests/unittest/include/suffix_number.h     |   1 +
 tests/unittest/include/syslinux/bootrm.h   |   1 +
 tests/unittest/include/syslinux/firmware.h |   1 +
 tests/unittest/include/syslinux/linux.h    |   1 +
 tests/unittest/include/syslinux/video.h    |   1 +
 7 files changed, 206 insertions(+), 1 deletion(-)

diff --git a/com32/lib/syslinux/tests/Makefile b/com32/lib/syslinux/tests/Makefile
index 701ac01..18b40fc 100644
--- a/com32/lib/syslinux/tests/Makefile
+++ b/com32/lib/syslinux/tests/Makefile
@@ -1,6 +1,6 @@
 CFLAGS = -I$(topdir)/tests/unittest/include
 
-tests = zonelist movebits memscan
+tests = zonelist movebits memscan load_linux
 .INTERMEDIATE: $(tests)
 
 all: banner $(tests)
@@ -14,6 +14,7 @@ harness-files = test-harness.c
 zonelist: zonelist.c ../zonelist.c $(harness-files)
 movebits: movebits.c ../movebits.c $(harness-files)
 memscan: memscan.c ../memscan.c
+load_linux: load_linux.c
 
 %: %.c
 	$(CC) $(CFLAGS) -o $@ $<
diff --git a/com32/lib/syslinux/tests/load_linux.c b/com32/lib/syslinux/tests/load_linux.c
new file mode 100644
index 0000000..ed97384
--- /dev/null
+++ b/com32/lib/syslinux/tests/load_linux.c
@@ -0,0 +1,199 @@
+#include "unittest/unittest.h"
+#include "unittest/memmap.h"
+
+#include "syslinux/bootrm.h"
+#include <string.h>
+
+/*
+ * load_linux.c dependencies.
+ */
+#include "../../suffix_number.c"
+
+static struct firmware __test_firmware;
+struct firmware *firmware = &__test_firmware;
+
+static struct syslinux_memmap *__test_mmap;
+struct syslinux_memmap *syslinux_memory_map(void)
+{
+    return syslinux_dup_memmap(__test_mmap);
+}
+
+void syslinux_force_text_mode(void) { }
+
+static char *__test_cmdline = "this is a test!!";
+static bool __test_called_boot_rm = false;
+static addr_t __test_cmdline_addr;
+
+int syslinux_shuffle_boot_rm(struct syslinux_movelist *fraglist,
+			     struct syslinux_memmap *memmap,
+			     uint16_t bootflags,
+			     struct syslinux_rm_regs *regs)
+{
+    struct syslinux_movelist *moves, *ml;
+    int rv;
+
+    __test_called_boot_rm = true;
+
+    ml = fraglist;
+    while (ml) {
+	addr_t cmdline_addr, last_lowmem_addr;
+
+	if (ml->src != __test_cmdline)
+	    continue;
+
+	last_lowmem_addr = __test_cmdline_addr;
+	cmdline_addr = ml->dst;
+	syslinux_assert_str(cmdline_addr == last_lowmem_addr,
+			    "cmdline at 0x%x but expected 0x%x",
+			    cmdline_addr, last_lowmem_addr);
+
+	syslinux_assert_str(strlen(__test_cmdline) + 1 == ml->len,
+			    "cmdline length %d, expected %d", ml->len,
+			    strlen(__test_cmdline) + 1);
+	break;
+    }
+
+    moves = NULL;
+    rv = syslinux_compute_movelist(&moves, fraglist, memmap);
+    syslinux_free_movelist(moves);
+
+    syslinux_assert(!rv, "Failed to compute movelist");
+
+    return -1;
+}
+
+#include "../load_linux.c"
+#include "../zonelist.c"
+#include "test-harness.c"
+
+static void __test_setup_kernel(void *buf)
+{
+    struct linux_header *hdr;
+
+    hdr = buf;
+    memset(hdr, 0, sizeof(*hdr));
+
+    /*
+     * Setup the minimum required fields.
+     */
+    hdr->boot_flag = BOOT_MAGIC;
+    hdr->setup_sects = 1;
+    hdr->version = 0x0201;
+}
+
+static inline addr_t __test_calc_cmdline_addr(addr_t addr)
+{
+    size_t len = strlen(__test_cmdline) + 1;
+    return (addr - len) & ~15;
+}
+
+#define KERNEL_BUF_SIZE		1024
+static void *__test_setup(struct test_memmap_entry *entries,
+			  size_t nr_entries,
+			  addr_t last)
+{
+    struct syslinux_memmap *mmap;
+    void *buf;
+
+    mmap = test_build_mmap(entries, nr_entries);
+    if (!mmap)
+	goto bail;
+
+    buf = malloc(KERNEL_BUF_SIZE);
+    if (!buf)
+	goto bail;
+
+    __test_setup_kernel(buf);
+
+    __test_mmap = mmap;
+    __test_cmdline_addr = __test_calc_cmdline_addr(last);
+
+    return buf;
+
+bail:
+    syslinux_free_memmap(mmap);
+    return NULL;
+}
+
+static void __test_teardown(void *buf)
+{
+    free(buf);
+    syslinux_free_memmap(__test_mmap);
+
+    __test_called_boot_rm = false;
+    __test_cmdline_addr = 0;
+    __test_mmap = NULL;
+}
+
+/*
+ * Make sure that we can relocate the cmdline to a free region of
+ * memory.
+ *
+ * The below memory map is based on one from VMWare.
+ */
+static int test_cmdline_placement(void)
+{
+    struct syslinux_memmap *mmap;
+    addr_t addr;
+    void *buf;
+    int rv;
+
+    struct test_memmap_entry entries[] = {
+	0x00000000, 0x00092800, SMT_FREE,
+	0x00092800, 0x0000d800, SMT_RESERVED,
+	0x000ca000, 0x00002000, SMT_RESERVED,
+	0x000dc000, 0x00004000, SMT_RESERVED,
+	0x000e4000, 0x00001c00, SMT_RESERVED,
+	0x00100000, 0x3fdf0000, SMT_FREE,
+    };
+
+    buf = __test_setup(entries, array_sz(entries), 0x92800);
+    if (!buf)
+	return -1;
+
+    rv = syslinux_boot_linux(buf, KERNEL_BUF_SIZE, NULL, NULL, __test_cmdline);
+
+    syslinux_assert(__test_called_boot_rm,
+		    "Failed to invoke syslinux_shuffle_boot_rm()");
+
+    __test_teardown(buf);
+    return 0;
+}
+
+/*
+ * Ensure that the linux loader only uses SMT_TERMINAL regions as a last
+ * resort.
+ */
+static int test_terminal_regions(void)
+{
+    addr_t addr;
+    void *buf;
+    int rv;
+
+    struct test_memmap_entry entries[] = {
+	0x000000, 0x090000, SMT_RESERVED,
+	0x090000, 0x000420, SMT_TERMINAL,
+	0x090420, 0x000400, SMT_FREE,
+	0x090820, 0x000200, SMT_TERMINAL,
+    };
+
+    buf = __test_setup(entries, array_sz(entries), 0x090820);
+    if (!buf)
+	return -1;
+
+    rv = syslinux_boot_linux(buf, KERNEL_BUF_SIZE, NULL, NULL, __test_cmdline);
+
+    syslinux_assert(__test_called_boot_rm,
+		    "Failed to invoke syslinux_shuffle_boot_rm()");
+
+    __test_teardown(buf);
+    return 0;
+}
+
+int main(int argc, char **argv)
+{
+    test_cmdline_placement();
+    test_terminal_regions();
+
+    return 0;
+}
diff --git a/tests/unittest/include/suffix_number.h b/tests/unittest/include/suffix_number.h
new file mode 100644
index 0000000..33883d2
--- /dev/null
+++ b/tests/unittest/include/suffix_number.h
@@ -0,0 +1 @@
+#include <../../../com32/include/suffix_number.h>
diff --git a/tests/unittest/include/syslinux/bootrm.h b/tests/unittest/include/syslinux/bootrm.h
new file mode 100644
index 0000000..c36d96e
--- /dev/null
+++ b/tests/unittest/include/syslinux/bootrm.h
@@ -0,0 +1 @@
+#include <../../../com32/include/syslinux/bootrm.h>
diff --git a/tests/unittest/include/syslinux/firmware.h b/tests/unittest/include/syslinux/firmware.h
new file mode 100644
index 0000000..cd3e9b3
--- /dev/null
+++ b/tests/unittest/include/syslinux/firmware.h
@@ -0,0 +1 @@
+#include <../../../com32/include/syslinux/firmware.h>
diff --git a/tests/unittest/include/syslinux/linux.h b/tests/unittest/include/syslinux/linux.h
new file mode 100644
index 0000000..99b85b7
--- /dev/null
+++ b/tests/unittest/include/syslinux/linux.h
@@ -0,0 +1 @@
+#include <../../../com32/include/syslinux/linux.h>
diff --git a/tests/unittest/include/syslinux/video.h b/tests/unittest/include/syslinux/video.h
new file mode 100644
index 0000000..c019754
--- /dev/null
+++ b/tests/unittest/include/syslinux/video.h
@@ -0,0 +1 @@
+#include <../../../com32/include/syslinux/video.h>


More information about the Syslinux-commits mailing list