summaryrefslogtreecommitdiff
path: root/com32/lib/syslinux
diff options
context:
space:
mode:
Diffstat (limited to 'com32/lib/syslinux')
-rw-r--r--com32/lib/syslinux/tests/Makefile3
-rw-r--r--com32/lib/syslinux/tests/load_linux.c199
2 files changed, 201 insertions, 1 deletions
diff --git a/com32/lib/syslinux/tests/Makefile b/com32/lib/syslinux/tests/Makefile
index 701ac01b..18b40fc5 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 00000000..ed973841
--- /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;
+}