[syslinux:master] Change fdt-specific loader into a generic setup_data loader

syslinux-bot for H. Peter Anvin hpa at linux.intel.com
Fri Jun 29 15:18:03 PDT 2012


Commit-ID:  443ce2a3ac055b4ec13f86a782a04be8453fd393
Gitweb:     http://www.syslinux.org/commit/443ce2a3ac055b4ec13f86a782a04be8453fd393
Author:     H. Peter Anvin <hpa at linux.intel.com>
AuthorDate: Fri, 29 Jun 2012 15:16:03 -0700
Committer:  H. Peter Anvin <hpa at linux.intel.com>
CommitDate: Fri, 29 Jun 2012 15:16:03 -0700

Change fdt-specific loader into a generic setup_data loader

Make it a generic setup_data loader keyed by type.

Signed-off-by: H. Peter Anvin <hpa at linux.intel.com>
Cc: Thierry Reding <thierry.reding at avionic-design.de>

---
 com32/include/syslinux/linux.h  |   26 ++++++++++---------
 com32/lib/Makefile              |    2 +-
 com32/lib/syslinux/fdt.c        |   28 --------------------
 com32/lib/syslinux/load_linux.c |   53 ++++++++++++++++++++-------------------
 com32/lib/syslinux/setup_data.c |   47 ++++++++++++++++++++++++++++++++++
 com32/modules/linux.c           |    2 +-
 6 files changed, 90 insertions(+), 68 deletions(-)

diff --git a/com32/include/syslinux/linux.h b/com32/include/syslinux/linux.h
index 6a5c2db..22ee5d5 100644
--- a/com32/include/syslinux/linux.h
+++ b/com32/include/syslinux/linux.h
@@ -51,17 +51,16 @@ struct initramfs {
 };
 #define INITRAMFS_MAX_ALIGN	4096
 
-struct fdt {
-	void *data;
-	size_t len;
-};
-#define DEVICETREE_MAX_ALIGN	4096
-
-struct setup_data {
+struct setup_data_header {
 	uint64_t next;
 	uint32_t type;
 	uint32_t len;
-	uint8_t data[0];
+} __packed;
+
+struct setup_data {
+    struct setup_data *prev, *next;
+    const void *data;
+    struct setup_data_header hdr;
 };
 
 #define SETUP_NONE	0
@@ -69,7 +68,8 @@ struct setup_data {
 #define SETUP_DTB	2
 
 int syslinux_boot_linux(void *kernel_buf, size_t kernel_size,
-			struct initramfs *initramfs, struct fdt *fdt,
+			struct initramfs *initramfs,
+			struct setup_data *setup_data,
 			char *cmdline);
 
 /* Initramfs manipulation functions */
@@ -88,9 +88,11 @@ int initramfs_load_file(struct initramfs *ihead, const char *src_filename,
 int initramfs_add_trailer(struct initramfs *ihead);
 int initramfs_load_archive(struct initramfs *ihead, const char *filename);
 
-/* Device Tree manipulation functions */
+/* Setup data manipulation functions */
 
-struct fdt *fdt_init(void);
-int fdt_load(struct fdt *fdt, const char *filename);
+int setup_data_add(struct setup_data *head, uint32_t type,
+		   const void *data, size_t data_len);
+int setup_data_load(struct setup_data *head, uint32_t type,
+		    const char *filename);
 
 #endif /* _SYSLINUX_LINUX_H */
diff --git a/com32/lib/Makefile b/com32/lib/Makefile
index a4959f6..5ab1fac 100644
--- a/com32/lib/Makefile
+++ b/com32/lib/Makefile
@@ -131,7 +131,7 @@ LIBOBJS = \
 	\
 	syslinux/disk.o							\
 	\
-	syslinux/fdt.o
+	syslinux/setup_data.o
 
 # These are the objects which are also imported into the core
 LIBCOREOBJS = 	\
diff --git a/com32/lib/syslinux/fdt.c b/com32/lib/syslinux/fdt.c
deleted file mode 100644
index 1bcd90b..0000000
--- a/com32/lib/syslinux/fdt.c
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <stdlib.h>
-#include <syslinux/linux.h>
-#include <syslinux/loadfile.h>
-
-struct fdt *fdt_init(void)
-{
-	struct fdt *fdt;
-
-	fdt = calloc(1, sizeof(*fdt));
-	if (!fdt)
-		return NULL;
-
-	return fdt;
-}
-
-int fdt_load(struct fdt *fdt, const char *filename)
-{
-	void *data;
-	size_t len;
-
-	if (loadfile(filename, &data, &len))
-		return -1;
-
-	fdt->data = data;
-	fdt->len = len;
-
-	return 0;
-}
diff --git a/com32/lib/syslinux/load_linux.c b/com32/lib/syslinux/load_linux.c
index b68aef7..86fc07f 100644
--- a/com32/lib/syslinux/load_linux.c
+++ b/com32/lib/syslinux/load_linux.c
@@ -180,7 +180,8 @@ static int map_initramfs(struct syslinux_movelist **fraglist,
 }
 
 int syslinux_boot_linux(void *kernel_buf, size_t kernel_size,
-			struct initramfs *initramfs, struct fdt *fdt,
+			struct initramfs *initramfs,
+			struct setup_data *setup_data,
 			char *cmdline)
 {
     struct linux_header hdr, *whdr;
@@ -188,6 +189,7 @@ int syslinux_boot_linux(void *kernel_buf, size_t kernel_size,
     addr_t real_mode_base, prot_mode_base;
     addr_t irf_size;
     size_t cmdline_size, cmdline_offset;
+    struct setup_data *sdp;
     struct syslinux_rm_regs regs;
     struct syslinux_movelist *fraglist = NULL;
     struct syslinux_memmap *mmap = NULL;
@@ -450,42 +452,41 @@ int syslinux_boot_linux(void *kernel_buf, size_t kernel_size,
 	}
     }
 
-    if (fdt && fdt->len > 0) {
-	const addr_t align_mask = DEVICETREE_MAX_ALIGN - 1;
-	struct syslinux_memmap *ml;
-	struct setup_data *setup;
-	addr_t best_addr = 0;
-	size_t size;
+    if (setup_data) {
+	uint64_t *prev_ptr = &whdr->setup_data;
 
-	size = sizeof(*setup) + fdt->len;
-
-	setup = malloc(size);
-	if (!setup)
-		goto bail;
+	for (sdp = setup_data->next; sdp != setup_data; sdp = sdp->next) {
+	    struct syslinux_memmap *ml;
+	    const addr_t align_mask = 15; /* Header is 16 bytes */
+	    addr_t best_addr = 0;
+	    size_t size = sdp->hdr.len + sizeof(sdp->hdr);
 
-	setup->next = 0;
-	setup->type = SETUP_DTB;
-	setup->len = fdt->len;
-	memcpy(setup->data, fdt->data, fdt->len);
+	    if (!sdp->data || !sdp->hdr.len)
+		continue;
 
-	for (ml = amap; ml->type != SMT_END; ml = ml->next) {
+	    for (ml = amap; ml->type != SMT_END; ml = ml->next) {
 		addr_t adj_start = (ml->start + align_mask) & ~align_mask;
 		addr_t adj_end = ml->next->start & ~align_mask;
 
 		if (ml->type == SMT_FREE && adj_end - adj_start >= size)
-			best_addr = (adj_end - size) & ~align_mask;
-	}
+		    best_addr = (adj_end - size) & ~align_mask;
+	    }
 
-	if (!best_addr)
+	    if (!best_addr)
 		goto bail;
 
-	whdr->setup_data = best_addr;
-
-	if (syslinux_add_memmap(&amap, best_addr, size, SMT_ALLOC))
-	    goto bail;
+	    *prev_ptr = best_addr;
+	    prev_ptr = &sdp->hdr.next;
 
-	if (syslinux_add_movelist(&fraglist, best_addr, (addr_t) setup, size))
-	    goto bail;
+	    if (syslinux_add_memmap(&amap, best_addr, size, SMT_ALLOC))
+		goto bail;
+	    if (syslinux_add_movelist(&fraglist, best_addr,
+				      (addr_t)&sdp->hdr, sizeof sdp->hdr))
+		goto bail;
+	    if (syslinux_add_movelist(&fraglist, best_addr + sizeof sdp->hdr,
+				      (addr_t)sdp->data, sdp->hdr.len))
+		goto bail;
+	}
     }
 
     /* Set up the registers on entry */
diff --git a/com32/lib/syslinux/setup_data.c b/com32/lib/syslinux/setup_data.c
new file mode 100644
index 0000000..a36c5b6
--- /dev/null
+++ b/com32/lib/syslinux/setup_data.c
@@ -0,0 +1,47 @@
+#include <stdlib.h>
+#include <syslinux/linux.h>
+#include <syslinux/loadfile.h>
+
+struct setup_data *setup_data_init(void)
+{
+    struct setup_data *setup_data;
+
+    setup_data = zalloc(sizeof(*setup_data));
+    if (!setup_data)
+	return NULL;
+
+    setup_data->prev = setup_data->next = setup_data;
+    return setup_data;
+}
+
+int setup_data_add(struct setup_data *head, uint32_t type,
+		   const void *data, size_t data_len)
+{
+	struct setup_data *setup_data;
+
+	setup_data = zalloc(sizeof(*setup_data));
+	if (!setup_data)
+	    return -1;
+
+	setup_data->data     = data;
+	setup_data->hdr.len  = data_len;
+	setup_data->hdr.type = type;
+	setup_data->prev     = head->prev;
+	setup_data->next     = head;
+	head->prev->next     = setup_data;
+	head->prev           = setup_data;
+
+	return 0;
+}
+
+int setup_data_load(struct setup_data *head, uint32_t type,
+		    const char *filename)
+{
+	void *data;
+	size_t len;
+
+	if (loadfile(filename, &data, &len))
+		return -1;
+
+	return setup_data_add(head, type, data, len);
+}
diff --git a/com32/modules/linux.c b/com32/modules/linux.c
index 679996c..102e877 100644
--- a/com32/modules/linux.c
+++ b/com32/modules/linux.c
@@ -224,7 +224,7 @@ int main(int argc, char *argv[])
 
     /* This should not return... */
     errno = 0;
-    syslinux_boot_linux(kernel_data, kernel_len, initramfs, cmdline);
+    syslinux_boot_linux(kernel_data, kernel_len, initramfs, NULL, cmdline);
     fprintf(stderr, "syslinux_boot_linux() failed: ");
 
 bail:


More information about the Syslinux-commits mailing list