gfx_done();
- syslinux_boot_linux(kernel, kernel_size, initrd, arg);
+ syslinux_boot_linux(kernel, kernel_size, initrd, NULL, arg);
}
};
#define INITRAMFS_MAX_ALIGN 4096
+struct fdt {
+ void *data;
+ size_t len;
+};
+#define DEVICETREE_MAX_ALIGN 4096
+
+struct setup_data {
+ uint64_t next;
+ uint32_t type;
+ uint32_t len;
+ uint8_t data[0];
+};
+
+#define SETUP_NONE 0
+#define SETUP_E820_EXT 1
+#define SETUP_DTB 2
+
int syslinux_boot_linux(void *kernel_buf, size_t kernel_size,
- struct initramfs *initramfs, char *cmdline);
+ struct initramfs *initramfs, struct fdt *fdt,
+ char *cmdline);
/* Initramfs manipulation functions */
int initramfs_add_trailer(struct initramfs *ihead);
int initramfs_load_archive(struct initramfs *ihead, const char *filename);
+/* Device Tree manipulation functions */
+
+struct fdt *fdt_init(void);
+int fdt_load(struct fdt *fdt, const char *filename);
+
#endif /* _SYSLINUX_LINUX_H */
syslinux/video/fontquery.o syslinux/video/forcetext.o \
syslinux/video/reportmode.o \
\
- syslinux/disk.o
+ syslinux/disk.o \
+ \
+ syslinux/fdt.o
# These are the objects which are also imported into the core
LIBCOREOBJS = \
--- /dev/null
+#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;
+}
}
int syslinux_boot_linux(void *kernel_buf, size_t kernel_size,
- struct initramfs *initramfs, char *cmdline)
+ struct initramfs *initramfs, struct fdt *fdt,
+ char *cmdline)
{
struct linux_header hdr, *whdr;
size_t real_mode_size, prot_mode_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;
+
+ size = sizeof(*setup) + fdt->len;
+
+ setup = malloc(size);
+ if (!setup)
+ goto bail;
+
+ setup->next = 0;
+ setup->type = SETUP_DTB;
+ setup->len = fdt->len;
+ memcpy(setup->data, fdt->data, fdt->len);
+
+ 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;
+ }
+
+ if (!best_addr)
+ goto bail;
+
+ whdr->setup_data = best_addr;
+
+ if (syslinux_add_memmap(&amap, best_addr, size, SMT_ALLOC))
+ goto bail;
+
+ if (syslinux_add_movelist(&fraglist, best_addr, (addr_t) setup, size))
+ goto bail;
+ }
+
/* Set up the registers on entry */
memset(®s, 0, sizeof regs);
regs.es = regs.ds = regs.ss = regs.fs = regs.gs = real_mode_base >> 4;
msleep(10000);
*/
- ret = syslinux_boot_linux(kernel_data, kernel_len, initramfs, newcmdline);
+ ret = syslinux_boot_linux(kernel_data, kernel_len, initramfs, NULL, newcmdline);
printf("syslinux_boot_linux returned %d\n", ret);
(void)mem_limit;
return syslinux_boot_linux(kernel->data, kernel->size,
- initramfs, (char *)cmdline);
+ initramfs, NULL, (char *)cmdline);
}
static int sl_derivative(lua_State * L)