cbfstool: add --xip support to add-stage for x86
Instead of going through the locate then add-stage dance while linking romstage twice allow for adding romstage with --xip flags to perform the relocation while adding it into CBFS. The -P (page-size) and -a (alignment) parameters were added as well so one could specify the necessary parameters for x86 romstage. BUG=chrome-os-partner:44827 BRANCH=None TEST=Built and booted on glados. Change-Id: I585619886f257e35f00961a1574009a51c28ff2b Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/11669 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
This commit is contained in:
@@ -15,6 +15,7 @@ CBFSTOOL_BINARY:=$(obj)/cbfstool
|
|||||||
CBFSTOOL_COMMON:=common.o cbfs_image.o compress.o fit.o
|
CBFSTOOL_COMMON:=common.o cbfs_image.o compress.o fit.o
|
||||||
CBFSTOOL_COMMON+=elfheaders.o cbfs-mkstage.o cbfs-mkpayload.o xdr.o
|
CBFSTOOL_COMMON+=elfheaders.o cbfs-mkstage.o cbfs-mkpayload.o xdr.o
|
||||||
CBFSTOOL_COMMON+=partitioned_file.o linux_trampoline.o cbfs-payload-linux.o
|
CBFSTOOL_COMMON+=partitioned_file.o linux_trampoline.o cbfs-payload-linux.o
|
||||||
|
CBFSTOOL_COMMON+=rmodule.o
|
||||||
# LZMA
|
# LZMA
|
||||||
CBFSTOOL_COMMON+=lzma/lzma.o
|
CBFSTOOL_COMMON+=lzma/lzma.o
|
||||||
CBFSTOOL_COMMON+=lzma/C/LzFind.o lzma/C/LzmaDec.o lzma/C/LzmaEnc.o
|
CBFSTOOL_COMMON+=lzma/C/LzFind.o lzma/C/LzmaDec.o lzma/C/LzmaEnc.o
|
||||||
|
@@ -6,6 +6,7 @@ cbfsobj += cbfs_image.o
|
|||||||
cbfsobj += cbfs-mkstage.o
|
cbfsobj += cbfs-mkstage.o
|
||||||
cbfsobj += cbfs-mkpayload.o
|
cbfsobj += cbfs-mkpayload.o
|
||||||
cbfsobj += elfheaders.o
|
cbfsobj += elfheaders.o
|
||||||
|
cbfsobj += rmodule.o
|
||||||
cbfsobj += xdr.o
|
cbfsobj += xdr.o
|
||||||
cbfsobj += fit.o
|
cbfsobj += fit.o
|
||||||
cbfsobj += partitioned_file.o
|
cbfsobj += partitioned_file.o
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include "elfparsing.h"
|
#include "elfparsing.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "cbfs.h"
|
#include "cbfs.h"
|
||||||
|
#include "rmodule.h"
|
||||||
|
|
||||||
/* Checks if program segment contains the ignored section */
|
/* Checks if program segment contains the ignored section */
|
||||||
static int is_phdr_ignored(Elf64_Phdr *phdr, Elf64_Shdr *shdr)
|
static int is_phdr_ignored(Elf64_Phdr *phdr, Elf64_Shdr *shdr)
|
||||||
@@ -90,6 +91,21 @@ static Elf64_Shdr *find_ignored_section_header(struct parsed_elf *pelf,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fill_cbfs_stage(struct buffer *outheader, enum comp_algo algo,
|
||||||
|
uint64_t entry, uint64_t loadaddr,
|
||||||
|
uint32_t filesize, uint32_t memsize)
|
||||||
|
{
|
||||||
|
/* N.B. The original plan was that SELF data was B.E.
|
||||||
|
* but: this is all L.E.
|
||||||
|
* Maybe we should just change the spec.
|
||||||
|
*/
|
||||||
|
xdr_le.put32(outheader, algo);
|
||||||
|
xdr_le.put64(outheader, entry);
|
||||||
|
xdr_le.put64(outheader, loadaddr);
|
||||||
|
xdr_le.put32(outheader, filesize);
|
||||||
|
xdr_le.put32(outheader, memsize);
|
||||||
|
}
|
||||||
|
|
||||||
/* returns size of result, or -1 if error.
|
/* returns size of result, or -1 if error.
|
||||||
* Note that, with the new code, this function
|
* Note that, with the new code, this function
|
||||||
* works for all elf files, not just the restricted set.
|
* works for all elf files, not just the restricted set.
|
||||||
@@ -262,18 +278,12 @@ int parse_elf_to_stage(const struct buffer *input, struct buffer *output,
|
|||||||
/* Set up for output marshaling. */
|
/* Set up for output marshaling. */
|
||||||
outheader.data = output->data;
|
outheader.data = output->data;
|
||||||
outheader.size = 0;
|
outheader.size = 0;
|
||||||
/* N.B. The original plan was that SELF data was B.E.
|
|
||||||
* but: this is all L.E.
|
|
||||||
* Maybe we should just change the spec.
|
|
||||||
*/
|
|
||||||
xdr_le.put32(&outheader, algo);
|
|
||||||
/* Coreboot expects entry point to be physical address. Thus, adjust the
|
/* Coreboot expects entry point to be physical address. Thus, adjust the
|
||||||
* entry point accordingly.
|
* entry point accordingly.
|
||||||
*/
|
*/
|
||||||
xdr_le.put64(&outheader, ehdr->e_entry + virt_to_phys);
|
fill_cbfs_stage(&outheader, algo, ehdr->e_entry + virt_to_phys,
|
||||||
xdr_le.put64(&outheader, data_start);
|
data_start, outlen, mem_end - data_start);
|
||||||
xdr_le.put32(&outheader, outlen);
|
|
||||||
xdr_le.put32(&outheader, mem_end - data_start);
|
|
||||||
|
|
||||||
if (*location)
|
if (*location)
|
||||||
*location -= sizeof(struct cbfs_stage);
|
*location -= sizeof(struct cbfs_stage);
|
||||||
@@ -284,3 +294,144 @@ err:
|
|||||||
parsed_elf_destroy(&pelf);
|
parsed_elf_destroy(&pelf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct xip_context {
|
||||||
|
struct rmod_context rmodctx;
|
||||||
|
size_t ignored_section_idx;
|
||||||
|
Elf64_Shdr *ignored_section;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int rmod_filter(struct reloc_filter *f, const Elf64_Rela *r)
|
||||||
|
{
|
||||||
|
size_t symbol_index;
|
||||||
|
int reloc_type;
|
||||||
|
struct parsed_elf *pelf;
|
||||||
|
Elf64_Sym *sym;
|
||||||
|
struct xip_context *xipctx;
|
||||||
|
|
||||||
|
xipctx = f->context;
|
||||||
|
pelf = &xipctx->rmodctx.pelf;
|
||||||
|
|
||||||
|
/* Allow everything through if there isn't an ignored section. */
|
||||||
|
if (xipctx->ignored_section == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
reloc_type = ELF64_R_TYPE(r->r_info);
|
||||||
|
symbol_index = ELF64_R_SYM(r->r_info);
|
||||||
|
sym = &pelf->syms[symbol_index];
|
||||||
|
|
||||||
|
/* Nothing to filter. Relocation is not being applied to the
|
||||||
|
* ignored section. */
|
||||||
|
if (sym->st_shndx != xipctx->ignored_section_idx)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* If there is any relocation to the ignored section that isn't
|
||||||
|
* absolute fail as current assumptions are that all relocations
|
||||||
|
* are absolute. */
|
||||||
|
if (reloc_type != R_386_32) {
|
||||||
|
ERROR("Invalid reloc to ignored section: %x\n", reloc_type);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Relocation referencing ignored section. Don't emit it. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse_elf_to_xip_stage(const struct buffer *input, struct buffer *output,
|
||||||
|
uint32_t *location, const char *ignore_section)
|
||||||
|
{
|
||||||
|
struct xip_context xipctx;
|
||||||
|
struct rmod_context *rmodctx;
|
||||||
|
struct reloc_filter filter;
|
||||||
|
struct parsed_elf *pelf;
|
||||||
|
size_t output_sz;
|
||||||
|
uint32_t adjustment;
|
||||||
|
struct buffer binput;
|
||||||
|
struct buffer boutput;
|
||||||
|
Elf64_Xword i;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
xipctx.ignored_section_idx = 0;
|
||||||
|
rmodctx = &xipctx.rmodctx;
|
||||||
|
pelf = &rmodctx->pelf;
|
||||||
|
|
||||||
|
if (rmodule_init(rmodctx, input))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Only support x86 XIP currently. */
|
||||||
|
if (rmodctx->pelf.ehdr.e_machine != EM_386) {
|
||||||
|
ERROR("Only support XIP stages for x86\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
xipctx.ignored_section =
|
||||||
|
find_ignored_section_header(pelf, ignore_section);
|
||||||
|
|
||||||
|
if (xipctx.ignored_section != NULL)
|
||||||
|
xipctx.ignored_section_idx =
|
||||||
|
xipctx.ignored_section - pelf->shdr;
|
||||||
|
|
||||||
|
filter.filter = rmod_filter;
|
||||||
|
filter.context = &xipctx;
|
||||||
|
|
||||||
|
if (rmodule_collect_relocations(rmodctx, &filter))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
output_sz = sizeof(struct cbfs_stage) + pelf->phdr->p_filesz;
|
||||||
|
if (buffer_create(output, output_sz, input->name) != 0) {
|
||||||
|
ERROR("Unable to allocate memory: %m\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
buffer_clone(&boutput, output);
|
||||||
|
memset(buffer_get(&boutput), 0, output_sz);
|
||||||
|
buffer_set_size(&boutput, 0);
|
||||||
|
|
||||||
|
/* Single loadable segment. The entire segment moves to final
|
||||||
|
* location from based on virtual address of loadable segment. */
|
||||||
|
adjustment = *location - pelf->phdr->p_vaddr;
|
||||||
|
DEBUG("Relocation adjustment: %08x\n", adjustment);
|
||||||
|
|
||||||
|
fill_cbfs_stage(&boutput, CBFS_COMPRESS_NONE,
|
||||||
|
(uint32_t)pelf->ehdr.e_entry + adjustment,
|
||||||
|
(uint32_t)pelf->phdr->p_vaddr + adjustment,
|
||||||
|
pelf->phdr->p_filesz, pelf->phdr->p_memsz);
|
||||||
|
/* Need an adjustable buffer. */
|
||||||
|
buffer_clone(&binput, input);
|
||||||
|
buffer_seek(&binput, pelf->phdr->p_offset);
|
||||||
|
bputs(&boutput, buffer_get(&binput), pelf->phdr->p_filesz);
|
||||||
|
|
||||||
|
buffer_clone(&boutput, output);
|
||||||
|
buffer_seek(&boutput, sizeof(struct cbfs_stage));
|
||||||
|
|
||||||
|
/* Make adjustments to all the relocations within the program. */
|
||||||
|
for (i = 0; i < rmodctx->nrelocs; i++) {
|
||||||
|
size_t reloc_offset;
|
||||||
|
uint32_t val;
|
||||||
|
struct buffer in, out;
|
||||||
|
|
||||||
|
/* The relocations represent in-program addresses of the
|
||||||
|
* linked program. Obtain the offset into the program to do
|
||||||
|
* the adjustment. */
|
||||||
|
reloc_offset = rmodctx->emitted_relocs[i] - pelf->phdr->p_vaddr;
|
||||||
|
|
||||||
|
buffer_clone(&out, &boutput);
|
||||||
|
buffer_seek(&out, reloc_offset);
|
||||||
|
buffer_clone(&in, &out);
|
||||||
|
/* Appease around xdr semantics: xdr decrements buffer
|
||||||
|
* size when get()ing and appends to size when put()ing. */
|
||||||
|
buffer_set_size(&out, 0);
|
||||||
|
|
||||||
|
val = xdr_le.get32(&in);
|
||||||
|
DEBUG("reloc %zx %08x -> %08x\n", reloc_offset, val,
|
||||||
|
val + adjustment);
|
||||||
|
xdr_le.put32(&out, val + adjustment);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Need to back up the location to include cbfs stage metadata. */
|
||||||
|
*location -= sizeof(struct cbfs_stage);
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
rmodule_cleanup(rmodctx);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@@ -74,6 +74,7 @@ static struct param {
|
|||||||
bool fill_partial_upward;
|
bool fill_partial_upward;
|
||||||
bool fill_partial_downward;
|
bool fill_partial_downward;
|
||||||
bool show_immutable;
|
bool show_immutable;
|
||||||
|
bool stage_xip;
|
||||||
int fit_empty_entries;
|
int fit_empty_entries;
|
||||||
enum comp_algo compression;
|
enum comp_algo compression;
|
||||||
/* for linux payloads */
|
/* for linux payloads */
|
||||||
@@ -115,6 +116,53 @@ static unsigned convert_to_from_top_aligned(const struct buffer *region,
|
|||||||
return image_size - region->offset - offset;
|
return image_size - region->offset - offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int do_cbfs_locate(int32_t *cbfs_addr, size_t metadata_size)
|
||||||
|
{
|
||||||
|
if (!param.filename) {
|
||||||
|
ERROR("You need to specify -f/--filename.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!param.name) {
|
||||||
|
ERROR("You need to specify -n/--name.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct cbfs_image image;
|
||||||
|
if (cbfs_image_from_buffer(&image, param.image_region,
|
||||||
|
param.headeroffset))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (cbfs_get_entry(&image, param.name))
|
||||||
|
WARN("'%s' already in CBFS.\n", param.name);
|
||||||
|
|
||||||
|
struct buffer buffer;
|
||||||
|
if (buffer_from_file(&buffer, param.filename) != 0) {
|
||||||
|
ERROR("Cannot load %s.\n", param.filename);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Include cbfs_file size along with space for with name. */
|
||||||
|
metadata_size += cbfs_calculate_file_header_size(param.name);
|
||||||
|
|
||||||
|
int32_t address = cbfs_locate_entry(&image, buffer.size, param.pagesize,
|
||||||
|
param.alignment, metadata_size);
|
||||||
|
buffer_delete(&buffer);
|
||||||
|
|
||||||
|
if (address == -1) {
|
||||||
|
ERROR("'%s' can't fit in CBFS for page-size %#x, align %#x.\n",
|
||||||
|
param.name, param.pagesize, param.alignment);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param.top_aligned)
|
||||||
|
address = -convert_to_from_top_aligned(param.image_region,
|
||||||
|
address);
|
||||||
|
|
||||||
|
*cbfs_addr = address;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
typedef int (*convert_buffer_t)(struct buffer *buffer, uint32_t *offset,
|
typedef int (*convert_buffer_t)(struct buffer *buffer, uint32_t *offset,
|
||||||
struct cbfs_file *header);
|
struct cbfs_file *header);
|
||||||
|
|
||||||
@@ -269,8 +317,26 @@ static int cbfstool_convert_mkstage(struct buffer *buffer, uint32_t *offset,
|
|||||||
{
|
{
|
||||||
struct buffer output;
|
struct buffer output;
|
||||||
int ret;
|
int ret;
|
||||||
ret = parse_elf_to_stage(buffer, &output, param.compression, offset,
|
|
||||||
param.ignore_section);
|
if (param.stage_xip) {
|
||||||
|
int32_t address;
|
||||||
|
|
||||||
|
if (do_cbfs_locate(&address, sizeof(struct cbfs_stage))) {
|
||||||
|
ERROR("Could not find location for XIP stage.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pass in a top aligned address. */
|
||||||
|
address = -convert_to_from_top_aligned(param.image_region,
|
||||||
|
address);
|
||||||
|
*offset = address;
|
||||||
|
|
||||||
|
ret = parse_elf_to_xip_stage(buffer, &output, offset,
|
||||||
|
param.ignore_section);
|
||||||
|
} else
|
||||||
|
ret = parse_elf_to_stage(buffer, &output, param.compression,
|
||||||
|
offset, param.ignore_section);
|
||||||
|
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return -1;
|
return -1;
|
||||||
buffer_delete(buffer);
|
buffer_delete(buffer);
|
||||||
@@ -328,53 +394,6 @@ static int cbfstool_convert_mkflatpayload(struct buffer *buffer,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_cbfs_locate(int32_t *cbfs_addr, size_t metadata_size)
|
|
||||||
{
|
|
||||||
if (!param.filename) {
|
|
||||||
ERROR("You need to specify -f/--filename.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!param.name) {
|
|
||||||
ERROR("You need to specify -n/--name.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct cbfs_image image;
|
|
||||||
if (cbfs_image_from_buffer(&image, param.image_region,
|
|
||||||
param.headeroffset))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (cbfs_get_entry(&image, param.name))
|
|
||||||
WARN("'%s' already in CBFS.\n", param.name);
|
|
||||||
|
|
||||||
struct buffer buffer;
|
|
||||||
if (buffer_from_file(&buffer, param.filename) != 0) {
|
|
||||||
ERROR("Cannot load %s.\n", param.filename);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Include cbfs_file size along with space for with name. */
|
|
||||||
metadata_size += cbfs_calculate_file_header_size(param.name);
|
|
||||||
|
|
||||||
int32_t address = cbfs_locate_entry(&image, buffer.size, param.pagesize,
|
|
||||||
param.alignment, metadata_size);
|
|
||||||
buffer_delete(&buffer);
|
|
||||||
|
|
||||||
if (address == -1) {
|
|
||||||
ERROR("'%s' can't fit in CBFS for page-size %#x, align %#x.\n",
|
|
||||||
param.name, param.pagesize, param.alignment);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (param.top_aligned)
|
|
||||||
address = -convert_to_from_top_aligned(param.image_region,
|
|
||||||
address);
|
|
||||||
|
|
||||||
*cbfs_addr = address;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t cbfs_default_metadata_size(void)
|
static size_t cbfs_default_metadata_size(void)
|
||||||
{
|
{
|
||||||
/* TODO Old cbfstool always assume input is a stage file (and adding
|
/* TODO Old cbfstool always assume input is a stage file (and adding
|
||||||
@@ -410,6 +429,18 @@ static int cbfs_add(void)
|
|||||||
|
|
||||||
static int cbfs_add_stage(void)
|
static int cbfs_add_stage(void)
|
||||||
{
|
{
|
||||||
|
if (param.stage_xip) {
|
||||||
|
if (param.baseaddress_assigned) {
|
||||||
|
ERROR("Cannot specify base address for XIP.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param.compression != CBFS_COMPRESS_NONE) {
|
||||||
|
ERROR("Cannot specify compression for XIP.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return cbfs_add_component(param.filename,
|
return cbfs_add_component(param.filename,
|
||||||
param.name,
|
param.name,
|
||||||
CBFS_COMPONENT_STAGE,
|
CBFS_COMPONENT_STAGE,
|
||||||
@@ -822,7 +853,7 @@ static const struct command commands[] = {
|
|||||||
{"add-flat-binary", "H:r:f:n:l:e:c:b:vh?", cbfs_add_flat_binary, true,
|
{"add-flat-binary", "H:r:f:n:l:e:c:b:vh?", cbfs_add_flat_binary, true,
|
||||||
true},
|
true},
|
||||||
{"add-payload", "H:r:f:n:t:c:b:C:I:vh?", cbfs_add_payload, true, true},
|
{"add-payload", "H:r:f:n:t:c:b:C:I:vh?", cbfs_add_payload, true, true},
|
||||||
{"add-stage", "H:r:f:n:t:c:b:S:vh?", cbfs_add_stage, true, true},
|
{"add-stage", "a:H:r:f:n:t:c:b:P:S:yvh?", cbfs_add_stage, true, true},
|
||||||
{"add-int", "H:r:i:n:b:vh?", cbfs_add_integer, true, true},
|
{"add-int", "H:r:i:n:b:vh?", cbfs_add_integer, true, true},
|
||||||
{"copy", "H:D:s:h?", cbfs_copy, true, true},
|
{"copy", "H:D:s:h?", cbfs_copy, true, true},
|
||||||
{"create", "M:r:s:B:b:H:o:m:vh?", cbfs_create, true, true},
|
{"create", "M:r:s:B:b:H:o:m:vh?", cbfs_create, true, true},
|
||||||
@@ -865,6 +896,7 @@ static struct option long_options[] = {
|
|||||||
{"type", required_argument, 0, 't' },
|
{"type", required_argument, 0, 't' },
|
||||||
{"verbose", no_argument, 0, 'v' },
|
{"verbose", no_argument, 0, 'v' },
|
||||||
{"with-readonly", no_argument, 0, 'w' },
|
{"with-readonly", no_argument, 0, 'w' },
|
||||||
|
{"xip", no_argument, 0, 'y' },
|
||||||
{NULL, 0, 0, 0 }
|
{NULL, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -941,6 +973,7 @@ static void usage(char *name)
|
|||||||
" (linux specific: [-C cmdline] [-I initrd])\n"
|
" (linux specific: [-C cmdline] [-I initrd])\n"
|
||||||
" add-stage [-r image,regions] -f FILE -n NAME \\\n"
|
" add-stage [-r image,regions] -f FILE -n NAME \\\n"
|
||||||
" [-c compression] [-b base] [-S section-to-ignore] "
|
" [-c compression] [-b base] [-S section-to-ignore] "
|
||||||
|
" [-a alignment] [-y|--xip] [-P page-size]"
|
||||||
"Add a stage to the ROM\n"
|
"Add a stage to the ROM\n"
|
||||||
" add-flat-binary [-r image,regions] -f FILE -n NAME \\\n"
|
" add-flat-binary [-r image,regions] -f FILE -n NAME \\\n"
|
||||||
" -l load-address -e entry-point [-c compression] \\\n"
|
" -l load-address -e entry-point [-c compression] \\\n"
|
||||||
@@ -1150,6 +1183,9 @@ int main(int argc, char **argv)
|
|||||||
case 'S':
|
case 'S':
|
||||||
param.ignore_section = optarg;
|
param.ignore_section = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'y':
|
||||||
|
param.stage_xip = true;
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
case '?':
|
case '?':
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
|
@@ -184,6 +184,9 @@ int parse_flat_binary_to_payload(const struct buffer *input,
|
|||||||
int parse_elf_to_stage(const struct buffer *input, struct buffer *output,
|
int parse_elf_to_stage(const struct buffer *input, struct buffer *output,
|
||||||
enum comp_algo algo, uint32_t *location,
|
enum comp_algo algo, uint32_t *location,
|
||||||
const char *ignore_section);
|
const char *ignore_section);
|
||||||
|
/* location is TOP aligned. */
|
||||||
|
int parse_elf_to_xip_stage(const struct buffer *input, struct buffer *output,
|
||||||
|
uint32_t *location, const char *ignore_section);
|
||||||
|
|
||||||
void print_supported_filetypes(void);
|
void print_supported_filetypes(void);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user