diff --git a/proxyclient/m1n1/proxy.py b/proxyclient/m1n1/proxy.py index 7a389d99..3a4807bc 100644 --- a/proxyclient/m1n1/proxy.py +++ b/proxyclient/m1n1/proxy.py @@ -514,6 +514,7 @@ class M1N1Proxy(Reloadable): P_KBOOT_SET_BOOTARGS = 0x701 P_KBOOT_SET_INITRD = 0x702 P_KBOOT_PREPARE_DT = 0x703 + P_KBOOT_PREPARE_FW = 0x704 P_PMGR_CLOCK_ENABLE = 0x800 P_PMGR_CLOCK_DISABLE = 0x801 @@ -852,6 +853,8 @@ class M1N1Proxy(Reloadable): self.request(self.P_KBOOT_SET_INITRD, base, size) def kboot_prepare_dt(self, dt_addr): return self.request(self.P_KBOOT_PREPARE_DT, dt_addr) + def kboot_prepare_fw(self, p_size): + return self.request(self.P_KBOOT_PREPARE_FW, p_size) def pmgr_clock_enable(self, clkid): return self.request(self.P_PMGR_CLOCK_ENABLE, clkid) diff --git a/proxyclient/tools/linux.py b/proxyclient/tools/linux.py index 0f946d69..f3650263 100755 --- a/proxyclient/tools/linux.py +++ b/proxyclient/tools/linux.py @@ -68,11 +68,24 @@ print("Kernel_base: 0x%x" % kernel_base) assert not (kernel_base & 0xffff) if initramfs is not None: - initramfs_base = u.memalign(65536, initramfs_size) - print("Loading %d initramfs bytes to 0x%x..." % (initramfs_size, initramfs_base)) - iface.writemem(initramfs_base, initramfs, True) - p.kboot_set_initrd(initramfs_base, initramfs_size) + psize = u.malloc(8) + fw = proxy.kboot_prepare_fw(psize) + if fw: + fw_size = p.read64(psize) + else: + fw_size = 0 + initramfs_base = initramfs_load = u.memalign(65536, initramfs_size + fw_size) + if fw_size: + print("Copying %d firmware bytes to 0x%x..." % (fw_size, initramfs_base + fw_size)) + p.memcpy(initramfs_base, fw, fw_size) + + print("Loading %d initramfs bytes to 0x%x..." % (initramfs_size, initramfs_base + fw_size)) + iface.writemem(initramfs_base + fw_size, initramfs, True) + p.kboot_set_initrd(initramfs_base, initramfs_size + fw_size) + + if fw: + p.free(fw) if args.u_boot: uboot = bytearray(args.u_boot.read_bytes()) diff --git a/src/cpio.c b/src/cpio.c index 0c8c8401..96dd21f8 100644 --- a/src/cpio.c +++ b/src/cpio.c @@ -118,12 +118,12 @@ size_t cpio_get_size(struct cpio *c) return sz; } -size_t cpio_finalize(struct cpio *c, u8 *bfr, size_t bfr_size) +int cpio_finalize(struct cpio *c, u8 *bfr, size_t bfr_size) { size_t off = 0; if (cpio_get_size(c) > bfr_size) - return 0; + return -1; for (u32 i = 0; i < c->n_files; ++i) { memcpy(bfr + off, &c->files[i].hdr, sizeof(struct cpio_header)); diff --git a/src/cpio.h b/src/cpio.h index d32ca160..9df18674 100644 --- a/src/cpio.h +++ b/src/cpio.h @@ -12,7 +12,7 @@ struct cpio *cpio_init(void); int cpio_add_file(struct cpio *c, const char *name, const u8 *bfr, size_t sz); int cpio_add_dir(struct cpio *c, const char *name); size_t cpio_get_size(struct cpio *c); -size_t cpio_finalize(struct cpio *c, u8 *bfr, size_t bfr_size); +int cpio_finalize(struct cpio *c, u8 *bfr, size_t bfr_size); void cpio_free(struct cpio *c); #endif diff --git a/src/kboot.c b/src/kboot.c index 9b842d35..6a5fe8ca 100644 --- a/src/kboot.c +++ b/src/kboot.c @@ -308,8 +308,8 @@ int kboot_prepare_dt(void *fdt) dt = NULL; } - if (kboot_prepare_fw() < 0) - bail("FDT: couldn't prepare firmware."); + if (!initrd_start) + initrd_start = kboot_prepare_fw(&initrd_size); dt_bufsize = fdt_totalsize(fdt); assert(dt_bufsize); @@ -368,13 +368,11 @@ static int kboot_prepare_sepfw(struct cpio *c) return 0; } -int kboot_prepare_fw(void) +void *kboot_prepare_fw(size_t *size) { struct cpio *c = cpio_init(); u8 *cpio_start = NULL; - u8 *new_initrd_start = NULL; size_t cpio_size = 0; - u32 new_initrd_size = 0; if (cpio_add_dir(c, "lib") < 0) goto err; @@ -386,33 +384,26 @@ int kboot_prepare_fw(void) if (kboot_prepare_sepfw(c) < 0) printf("kboot: no SEPFW found.\n"); + if (cpio_add_file(c, "TRAILER!!!", NULL, 0) < 0) + goto err; + cpio_size = cpio_get_size(c); - new_initrd_size = cpio_size + ALIGN_UP(initrd_size, 4); - new_initrd_start = memalign(INITRD_ALIGN, new_initrd_size); - if (!new_initrd_start) { - printf("kboot: couldn't allocate initrd buffer\n"); + cpio_start = memalign(INITRD_ALIGN, cpio_size); + int res = cpio_finalize(c, cpio_start, cpio_size); + if (res != (int)cpio_size) { + printf("kboot: unexpected cpio_finalize size: %d should be %lu\n", res, cpio_size); goto err; } - memcpy(new_initrd_start, initrd_start, initrd_size); + if (size) + *size = cpio_size; - cpio_start = new_initrd_start + ALIGN_UP(initrd_size, 4); - size_t res = cpio_finalize(c, cpio_start, cpio_size); - if (res != cpio_size) { - printf("kboot: unexpected cpio_finalize size: %lu should be %lu\n", res, cpio_size); - goto err; - } - - initrd_start = new_initrd_start; - initrd_size = new_initrd_size; cpio_free(c); - - return 0; + return cpio_start; err: - free(new_initrd_start); cpio_free(c); - return -1; + return NULL; } int kboot_boot(void *kernel) diff --git a/src/kboot.h b/src/kboot.h index 7f30406e..b7a4cfa1 100644 --- a/src/kboot.h +++ b/src/kboot.h @@ -19,7 +19,7 @@ struct kernel_header { void kboot_set_initrd(void *start, size_t size); void kboot_set_bootargs(const char *ba); -int kboot_prepare_fw(void); +void *kboot_prepare_fw(size_t *size); int kboot_prepare_dt(void *fdt); int kboot_boot(void *kernel); diff --git a/src/payload.c b/src/payload.c index 7b024912..ba93fd12 100644 --- a/src/payload.c +++ b/src/payload.c @@ -4,6 +4,7 @@ #include "assert.h" #include "heapblock.h" #include "kboot.h" +#include "malloc.h" #include "smp.h" #include "utils.h" @@ -104,6 +105,16 @@ static void *load_cpio(void *p, size_t size) return NULL; } + size_t fw_size; + void *fw = kboot_prepare_fw(&fw_size); + + if (fw) { + memmove((void *)(fw_size + (u64)p), p, size); + memcpy(p, fw, fw_size); + free(fw); + size += fw_size; + } + kboot_set_initrd(p, size); return ((u8 *)p) + size; } diff --git a/src/proxy.c b/src/proxy.c index dca53d56..cbd82762 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -351,6 +351,9 @@ int proxy_process(ProxyRequest *request, ProxyReply *reply) case P_KBOOT_PREPARE_DT: reply->retval = kboot_prepare_dt((void *)request->args[0]); break; + case P_KBOOT_PREPARE_FW: + reply->retval = (u64)kboot_prepare_fw((size_t *)request->args[0]); + break; case P_PMGR_CLOCK_ENABLE: reply->retval = pmgr_clock_enable(request->args[0]); diff --git a/src/proxy.h b/src/proxy.h index b5bdc3fe..327ebb14 100644 --- a/src/proxy.h +++ b/src/proxy.h @@ -90,6 +90,7 @@ typedef enum { P_KBOOT_SET_BOOTARGS, P_KBOOT_SET_INITRD, P_KBOOT_PREPARE_DT, + P_KBOOT_PREPARE_FW, P_PMGR_CLOCK_ENABLE = 0x800, // power/clock management ops P_PMGR_CLOCK_DISABLE,