+/* prepend a second image header and the bootloader.
+ *
+ * |------------|
+ * |image header|
+ * |------------|
+ * |bootloader |
+ * |------------|
+ * |optional pad|
+ * |------------|
+ * |image header|
+ * |------------|
+ * |kernel image|
+ * |------------|
+ * |rootfs image|
+ * |------------|
+ *
+ * The padding is optional. The second image header should begin a 64k boundary.
+ */
+int prepend_bootloader() {
+ unsigned int buflen = 0;
+ int ret = 0, bootloader_padded = 0;
+ char *buf = 0, *p = 0;
+ struct file_info image;
+
+ /* calculate blocks to ensure padding */
+ bootloader_padded = boot_info.file_size & (64 * 1024);
+ if (bootloader_padded < boot_info.file_size)
+ bootloader_padded += 64 * 1024;
+
+ image.file_name = ofname;
+ ret = get_file_stat(&image);
+ if (ret) {
+ ERR("Can not load the output image");
+ return ret;
+ }
+
+ buflen = image.file_size + bootloader_padded + sizeof(struct fw_header);
+ buf = malloc(buflen);
+ if (buf == NULL) {
+ ERR("Can not allocate buffer %d bytes", buflen);
+ return -1;
+ }
+ memset(buf, 0xff, buflen);
+
+ /* load old image */
+ p = buf + bootloader_padded + sizeof(struct fw_header);
+ ret = read_to_buf(&image, p);
+ if (ret) {
+ ERR("Can not read output image");
+ goto out_free_buf;
+ }
+
+ p = buf + sizeof(struct fw_header);
+ ret = read_to_buf(&boot_info, p);
+
+ _fill_header(buf, buflen, 1);
+
+ ret = write_fw(ofname, buf, buflen);
+ if (ret)
+ goto out_free_buf;
+
+ ret = EXIT_SUCCESS;
+
+out_free_buf:
+ free(buf);
+
+ return ret;
+}
+