diff --git a/util/cbfstool/Makefile b/util/cbfstool/Makefile index 50f97961bc..51b6bad9c1 100644 --- a/util/cbfstool/Makefile +++ b/util/cbfstool/Makefile @@ -1,42 +1,51 @@ -# -# -# - obj ?= $(shell pwd) -COMMANDS=create.o bootblock.o delete.o extract.o add.o print.o resize.o -OBJ=$(COMMANDS) cbfstool.o util.o fs.o -INC=cbfstool.h cbfs.h - -HOSTCC ?= gcc HOSTCXX ?= g++ +HOSTCC ?= gcc -CFLAGS=-g -Wall -W -Werror +BINARY:=$(obj)/cbfstool -DESTDIR ?= /usr/local/bin +COMMON:=common.o compress.o minilzma.o +COMMON+=LZMAEncoder.o LZInWindow.o +COMMON+=RangeCoderBit.o StreamUtils.o +COMMON+=OutBuffer.o Alloc.o CRC.o +COMMON+=cbfs-mkstage.o cbfs-mkpayload.o cbfstool.o -all: $(obj)/cbfstool $(obj)/tools/cbfs-mkpayload $(obj)/tools/cbfs-mkstage +COMMON:=$(addprefix $(obj)/,$(COMMON)) -$(obj)/cbfstool: $(patsubst %,$(obj)/%,$(OBJ)) - $(HOSTCC) -o $@ $(patsubst %,$(obj)/%,$(OBJ)) - -tobj = $(obj)/tools -tsrc = $(shell pwd)/tools - -include $(tsrc)/Makefile - -$(obj)/%.o: %.c $(INC) +$(obj)/%.o: %.c $(HOSTCC) $(CFLAGS) -c -o $@ $< -install: $(obj)/cbfstool $(obj)/tools/cbfs-mkpayload $(obj)/tools/cbfs-mkstage - @ install -d $(DESTDIR) - @ install -m 0755 $(obj)/cbfstool $(DESTDIR)/cbfstool - @ install -m 0755 $(obj)/tools/cbfs-mkstage $(DESTDIR)/cbfs-mkstage - @ install -m 0755 $(obj)/tools/cbfs-mkpayload $(DESTDIR)/cbfs-mkpayload +$(obj)/%.o: lzma/%.cc + $(HOSTCXX) $(CXXFLAGS) -c -o $@ $< + +$(obj)/%.o: lzma/C/7zip/Compress/LZMA/%.cpp + $(HOSTCXX) $(CXXFLAGS) -c -o $@ $< + +$(obj)/%.o: lzma/C/7zip/Compress/LZ/%.cpp + $(HOSTCXX) $(CXXFLAGS) -c -o $@ $< + +$(obj)/%.o: lzma/C/7zip/Compress/RangeCoder/%.cpp + $(HOSTCXX) $(CXXFLAGS) -c -o $@ $< + +$(obj)/%.o: lzma/C/7zip/Common/%.cpp + $(HOSTCXX) $(CXXFLAGS) -c -o $@ $< + +$(obj)/%.o: lzma/C/Common/%.cpp + $(HOSTCXX) $(CXXFLAGS) -c -o $@ $< + +all: $(BINARY) + +clean: + rm -f $(COMMON) $(BINARY) tags: - ctags *.[ch] */*.[ch] + ctags *.[ch] -clean: tools-clean - rm -f $(patsubst %,$(obj)/%,$(OBJ)) $(obj)/cbfstool +CXXFLAGS=-DCOMPACT -m32 +CFLAGS=-m32 +LDFLAGS=-m32 +$(obj)/cbfstool:$(COMMON) + $(HOSTCXX) $(LDFLAGS) -o $@ $^ + strip $@ diff --git a/util/cbfstool/Makefile.inc b/util/cbfstool/Makefile.inc index c93e1ca923..74bb5c0d6b 100644 --- a/util/cbfstool/Makefile.inc +++ b/util/cbfstool/Makefile.inc @@ -2,34 +2,56 @@ ifdef POST_EVALUATION cbfsobj := -# commands -cbfsobj += create.o -cbfsobj += bootblock.o -cbfsobj += delete.o -cbfsobj += extract.o -cbfsobj += add.o -cbfsobj += print.o -cbfsobj += resize.o -# main tool +cbfsobj += common.o +cbfsobj += compress.o +cbfsobj += minilzma.o +cbfsobj += LZMAEncoder.o +cbfsobj += LZInWindow.o +cbfsobj += RangeCoderBit.o +cbfsobj += StreamUtils.o +cbfsobj += OutBuffer.o +cbfsobj += Alloc.o +cbfsobj += CRC.o +cbfsobj += cbfs-mkstage.o +cbfsobj += cbfs-mkpayload.o cbfsobj += cbfstool.o -cbfsobj += util.o -cbfsobj += fs.o -cbfsinc := cbfstool.h cbfs.h +CBFSTOOLFLAGS=-m32 -DCOMPACT $(obj)/util/cbfstool: mkdir -p $@ - mkdir -p $@/tools/lzma $(obj)/util/cbfstool/%.o: $(top)/util/cbfstool/%.c printf " HOSTCC $(subst $(obj)/,,$(@))\n" - $(HOSTCC) $(HOSTCFLAGS) -c -o $@ $< + $(HOSTCC) $(CBFSTOOLFLAGS) $(HOSTCFLAGS) -c -o $@ $< -$(obj)/util/cbfstool/cbfstool: $(obj)/util/cbfstool $(obj)/util/cbfstool/tools/cbfs-mkpayload $(obj)/util/cbfstool/tools/cbfs-mkstage $(addprefix $(obj)/util/cbfstool/,$(cbfsobj)) - printf " HOSTCC $(subst $(obj)/,,$(@)) (link)\n" - $(HOSTCC) -o $@ $(addprefix $(obj)/util/cbfstool/,$(cbfsobj)) +$(obj)/util/cbfstool/%.o: $(top)/util/cbfstool/lzma/%.cc + printf " HOSTCXX $(subst $(obj)/,,$(@))\n" + $(HOSTCXX) $(CBFSTOOLFLAGS) $(HOSTCXXFLAGS) -c -o $@ $< + +$(obj)/util/cbfstool/%.o: $(top)/util/cbfstool/lzma/C/7zip/Compress/LZMA/%.cpp + printf " HOSTCXX $(subst $(obj)/,,$(@))\n" + $(HOSTCXX) $(CBFSTOOLFLAGS) $(HOSTCXXFLAGS) -c -o $@ $< + +$(obj)/util/cbfstool/%.o: $(top)/util/cbfstool/lzma/C/7zip/Compress/LZ/%.cpp + printf " HOSTCXX $(subst $(obj)/,,$(@))\n" + $(HOSTCXX) $(CBFSTOOLFLAGS) $(HOSTCXXFLAGS) -c -o $@ $< + +$(obj)/util/cbfstool/%.o: $(top)/util/cbfstool/lzma/C/7zip/Compress/RangeCoder/%.cpp + printf " HOSTCXX $(subst $(obj)/,,$(@))\n" + $(HOSTCXX) $(CBFSTOOLFLAGS) $(HOSTCXXFLAGS) -c -o $@ $< + +$(obj)/util/cbfstool/%.o: $(top)/util/cbfstool/lzma/C/7zip/Common/%.cpp + printf " HOSTCXX $(subst $(obj)/,,$(@))\n" + $(HOSTCXX) $(CBFSTOOLFLAGS) $(HOSTCXXFLAGS) -c -o $@ $< + +$(obj)/util/cbfstool/%.o: $(top)/util/cbfstool/lzma/C/Common/%.cpp + printf " HOSTCXX $(subst $(obj)/,,$(@))\n" + $(HOSTCXX) $(CBFSTOOLFLAGS) $(HOSTCXXFLAGS) -c -o $@ $< + +$(obj)/util/cbfstool/cbfstool: $(obj)/util/cbfstool $(addprefix $(obj)/util/cbfstool/,$(cbfsobj)) + printf " HOSTCXX $(subst $(obj)/,,$(@)) (link)\n" + $(HOSTCXX) $(CBFSTOOLFLAGS) -o $@ $(addprefix $(obj)/util/cbfstool/,$(cbfsobj)) endif -include $(top)/util/cbfstool/tools/Makefile.inc - diff --git a/util/cbfstool/README b/util/cbfstool/README index 9c8e818721..912ffa985f 100644 --- a/util/cbfstool/README +++ b/util/cbfstool/README @@ -100,7 +100,7 @@ component at runtime without disturbing the others. the ROM). This is to allow for arbitrary space to be left at the beginning of the ROM for things like embedded controller firmware. -'pad' rounds the header to 32 bits and reserves a little room for later use. +'pad' rounds the header to 32 bytes and reserves a little room for later use. = Bootblock = The bootblock is a mandatory component in the ROM. It is located in the @@ -123,7 +123,7 @@ unlimited size. Each CBFS component starts with a header: -struct CBFS_file { +struct cbfs_file { char magic[8]; unsigned int len; unsigned int type; @@ -335,24 +335,3 @@ the "don't care" component type. This can be used when the component type is not necessary (such as when the name of the component is unique. i.e. option_table). It is recommended that all components be assigned a unique type, but NULL can be used when the type does not matter. - - - - - - - - - - - - - - - - - - - - - diff --git a/util/cbfstool/TODO b/util/cbfstool/TODO deleted file mode 100644 index 0f8ed2718f..0000000000 --- a/util/cbfstool/TODO +++ /dev/null @@ -1,4 +0,0 @@ -Add interactive mode -Add script mode (./cbfstool [ROM] -s script) -Support compression for stages and payloads -Add nrv2b diff --git a/util/cbfstool/add.c b/util/cbfstool/add.c deleted file mode 100644 index f3be4fc0d7..0000000000 --- a/util/cbfstool/add.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - * cbfstool - * - * Copyright (C) 2008 Jordan Crouse - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "cbfstool.h" - -#define MAX_PATH 255 - -static int add_from_fd(struct rom *rom, const char *name, int type, int fd) -{ - unsigned char *buffer = malloc(16 * 1024); - unsigned char *ptr = buffer; - - int size = 0; - int aloc = 16 * 1024; - int remain = 16 * 1024; - int ret; - - if (buffer == NULL) - return -1; - - while (1) { - ret = read(fd, ptr, remain); - - if (ret <= 0) - break; - - ptr += ret; - remain -= ret; - size += ret; - - if (remain == 0) { - buffer = realloc(buffer, aloc + 16 * 1024); - - if (buffer == NULL) { - ret = -1; - break; - } - - ptr = buffer + size; - - aloc += (16 * 1024); - remain = 16 * 1024; - } - } - - if (ret == -1 || size == 0) { - - if (buffer != NULL) - free(buffer); - - return -1; - } - - ret = rom_add(rom, name, buffer, 0, size, type); - free(buffer); - - return ret; -} - -int fork_tool_and_add(struct rom *rom, const char *tool, const char *input, - const char *name, int type, int argc, char **argv) -{ - int output[2]; - pid_t pid; - int ret; - int status; - char **toolargs; - int i; - - /* Create the pipe */ - - if (pipe(output)) { - ERROR("Couldn't create a pipe: %m\n"); - return -1; - } - - toolargs = (char **)malloc((5 + argc) * sizeof(char *)); - - if (toolargs == NULL) { - ERROR("Unable to allocate memory: %m\n"); - return -1; - } - - toolargs[0] = (char *)tool; - - /* these are args. So they need a - in front */ - for (i = 0; i < argc; i++) { - /* I wish I had python */ - char *c = malloc(strlen(argv[i])) + 2; - c[0] = '-'; - strcpy(&c[1], argv[i]); - c[strlen(argv[i])+1] = 0; - toolargs[1 + i] = c; - } - - toolargs[1 + argc] = "-o"; - toolargs[2 + argc] = "-"; - toolargs[3 + argc] = (char *)input; - toolargs[4 + argc] = NULL; - - pid = fork(); - - if (pid == 0) { - - /* Set up stdin/stdout for the child */ - - dup2(output[1], STDOUT_FILENO); - close(output[0]); - - /* Execute the tool */ - if (execv(tool, toolargs)) { - ERROR("Unable to execute %s: %m\n", tool); - exit(-1); - } - - exit(0); - } - - free(toolargs); - - close(output[1]); - - /* Read from the file */ - ret = add_from_fd(rom, name, type, output[0]); - - /* Reap the child */ - waitpid(pid, &status, 0); - - if (WIFSIGNALED(status)) { - kill(pid, WTERMSIG(status)); - ERROR("Error while executing %s\n", tool); - return -1; - } else if (WEXITSTATUS(status) != 0) { - ERROR("Error while executing %s: %d\n", tool, - (int)WEXITSTATUS(status)); - return -1; - } - - return ret; -} - -static int add_blob(struct rom *rom, const char *filename, - const char *name, unsigned long address, int type) -{ - void *ptr; - struct stat s; - int fd, ret; - - if (!strcmp(filename, "-")) - return add_from_fd(rom, name, type, 0); - - fd = open(filename, O_RDONLY); - - if (fd == -1) { - ERROR("Could not open %s: %m\n", filename); - return -1; - } - - if (fstat(fd, &s)) { - ERROR("Could not stat %s: %m\n", filename); - close(fd); - return -1; - } - - ptr = mmap(0, s.st_size, PROT_READ, MAP_SHARED, fd, 0); - - if (ptr == MAP_FAILED) { - ERROR("Unable to map %s: %m\n", filename); - close(fd); - return -1; - } - - ret = rom_add(rom, name, ptr, address, s.st_size, type); - - munmap(ptr, s.st_size); - close(fd); - - return ret; -} - -void add_usage(void) -{ - printf("add FILE NAME TYPE [base address]\tAdd a component\n"); -} - -void add_stage_usage(void) -{ - printf("add-stage FILE NAME [OPTIONS]\tAdd a stage to the ROM\n"); -} - -void add_payload_usage(void) -{ - printf - ("add-payload FILE NAME [OPTIONS]\tAdd a payload to the ROM\n"); -} - -int select_component_type(char *s) -{ - int i = 0; - char *accepted_strings[] = { - "stage", - "payload", - "optionrom", - "deleted", - "free", - }; - for (i=0; i < 5; i++) - if (!strcmp(s, accepted_strings[i])) - return i; - return -1; -} - -int add_handler(struct rom *rom, int argc, char **argv) -{ - unsigned int type = CBFS_COMPONENT_NULL; - unsigned long address = 0; - - if ((argc < 3) || (argc > 4)) { - add_usage(); - return -1; - } - - if (argc > 3) { - address = strtoul(argv[3], 0, 0); - } - - if (!rom_exists(rom)) { - ERROR("You need to create the ROM before adding files to it\n"); - return -1; - } - - /* There are two ways to specify the type - a string or a number */ - - if (isdigit(*(argv[2]))) - type = strtoul(argv[2], 0, 0); - else { - switch(select_component_type(argv[2])) { - case 0: - type = CBFS_COMPONENT_STAGE; - break; - case 1: - type = CBFS_COMPONENT_PAYLOAD; - break; - case 2: - type = CBFS_COMPONENT_OPTIONROM; - break; - case 3: - type = CBFS_COMPONENT_DELETED; - break; - case 4: - type = CBFS_COMPONENT_NULL; - break; - default: - ERROR("Unrecognized component type %s.\nValid options are: stage, payload, optionrom, deleted, free.\n", argv[2]); - return -1; - } - } - - return add_blob(rom, argv[0], argv[1], address, type); -} - -char *find_tool(char *tool) -{ - static char toolpath[MAX_PATH]; - extern char cbfstool_bindir[]; - - snprintf(toolpath, MAX_PATH - 1, "tools/%s", tool); - if (!access(toolpath, X_OK)) - return toolpath; - - snprintf(toolpath, MAX_PATH - 1, "%s/tools/%s", cbfstool_bindir, tool); - - if (!access(toolpath, X_OK)) - return toolpath; - - snprintf(toolpath, MAX_PATH - 1, "%s/%s", cbfstool_bindir, tool); - - if (!access(toolpath, X_OK)) - return toolpath; - - strncpy(toolpath, tool, MAX_PATH - 1); - return toolpath; -} - -/* Invoke the cbfs-mkpayload utility */ - -int add_payload_handler(struct rom *rom, int argc, char **argv) -{ - if (argc < 2) { - add_payload_usage(); - return -1; - } - - /* Make sure the ROM exists */ - - if (!rom_exists(rom)) { - ERROR("You need to create the ROM before adding files to it\n"); - return -1; - } - - /* Check that the incoming file exists */ - - if (access(argv[0], R_OK)) { - ERROR("File %s does not exist\n", argv[0]); - return -1; - } - - return fork_tool_and_add(rom, find_tool("cbfs-mkpayload"), argv[0], - argv[1], CBFS_COMPONENT_PAYLOAD, argc - 2, - argc > 2 ? &argv[2] : NULL); -} - -/* Invoke the cbfs-mkstage utility */ - -int add_stage_handler(struct rom *rom, int argc, char **argv) -{ - if (argc < 2) { - add_stage_usage(); - return -1; - } - - /* Make sure the ROM exists */ - - if (!rom_exists(rom)) { - ERROR("You need to create the ROM before adding files to it\n"); - return -1; - } - - /* Check that the incoming file exists */ - - if (access(argv[0], R_OK)) { - ERROR("File %s does not exist\n", argv[0]); - return -1; - } - - return fork_tool_and_add(rom, find_tool("cbfs-mkstage"), argv[0], - argv[1], CBFS_COMPONENT_STAGE, argc - 2, - argc > 2 ? &argv[2] : NULL); -} diff --git a/util/cbfstool/bootblock.c b/util/cbfstool/bootblock.c deleted file mode 100644 index 11f362c1d2..0000000000 --- a/util/cbfstool/bootblock.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * cbfstool - * - * Copyright (C) 2008 Jordan Crouse - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -#include -#include -#include -#include "cbfstool.h" - -void bootblock_usage(void) -{ - printf("bootblock [FILE]\t\tAdd a bootblock to the ROM\n"); -} - -int bootblock_handler(struct rom *rom, int argc, char **argv) -{ - if (argc < 1) { - bootblock_usage(); - return -1; - } - - return add_bootblock(rom, argv[0]); -} diff --git a/util/cbfstool/tools/cbfs-mkpayload.c b/util/cbfstool/cbfs-mkpayload.c similarity index 69% rename from util/cbfstool/tools/cbfs-mkpayload.c rename to util/cbfstool/cbfs-mkpayload.c index 7db48cfa8b..4f0e248123 100644 --- a/util/cbfstool/tools/cbfs-mkpayload.c +++ b/util/cbfstool/cbfs-mkpayload.c @@ -2,6 +2,8 @@ * cbfs-mkpayload * * Copyright (C) 2008 Jordan Crouse + * 2009 coresystems GmbH + * written by Patrick Georgi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,10 +30,10 @@ #include #include "common.h" -#include "../cbfs.h" +#include "cbfs.h" -int parse_elf(unsigned char *input, unsigned char **output, int algo, - void (*compress) (char *, int, char *, int *)) +int parse_elf_to_payload(unsigned char *input, unsigned char **output, + comp_algo algo) { Elf32_Phdr *phdr; Elf32_Ehdr *ehdr; @@ -46,6 +48,10 @@ int parse_elf(unsigned char *input, unsigned char **output, int algo, struct cbfs_payload_segment *segs; int i; + comp_func_ptr compress = compression_function(algo); + if (!compress) + return -1; + ehdr = (Elf32_Ehdr *) input; headers = ehdr->e_phnum; header = (char *)ehdr; @@ -93,8 +99,7 @@ int parse_elf(unsigned char *input, unsigned char **output, int algo, /* Allocate a block of memory to store the data in */ sptr = - calloc((segments * sizeof(struct cbfs_payload_segment)) + isize, - 1); + calloc((segments * sizeof(struct cbfs_payload_segment)) + isize, 1); doffset = (segments * sizeof(struct cbfs_payload_segment)); if (sptr == NULL) @@ -141,7 +146,8 @@ int parse_elf(unsigned char *input, unsigned char **output, int algo, segs[segments].type = PAYLOAD_SEGMENT_BSS; segs[segments].load_addr = (unsigned long long)htonl(phdr[i].p_paddr); - segs[segments].mem_len = (unsigned int)htonl(phdr[i].p_memsz); + segs[segments].mem_len = + (unsigned int)htonl(phdr[i].p_memsz); segs[segments].offset = htonl(doffset); segments++; @@ -156,8 +162,7 @@ int parse_elf(unsigned char *input, unsigned char **output, int algo, int len; compress((char *)&header[phdr[i].p_offset], - phdr[i].p_filesz, - (char *)(sptr + doffset), &len); + phdr[i].p_filesz, (char *)(sptr + doffset), &len); segs[segments].len = htonl(len); /* If the compressed section is larger, then use the @@ -184,89 +189,6 @@ int parse_elf(unsigned char *input, unsigned char **output, int algo, return (segments * sizeof(struct cbfs_payload_segment)) + osize; -err: + err: return -1; } - -int main(int argc, char **argv) -{ - void (*compress) (char *, int, char *, int *); - int algo = CBFS_COMPRESS_NONE; - - char *output = NULL; - char *input = NULL; - - unsigned char *buffer, *obuffer; - int size, osize; - - while (1) { - int option_index; - static struct option longopt[] = { - {"output", 1, 0, 'o'}, - {"lzma", 0, 0, 'l'}, - {"nocompress", 0, 0, 'n'}, - }; - - signed char ch = getopt_long(argc, argv, "o:ln", - longopt, &option_index); - - if (ch == -1) - break; - - switch (ch) { - case 'o': - output = optarg; - break; - case 'l': - algo = CBFS_COMPRESS_LZMA; - break; - case 'n': - algo = CBFS_COMPRESS_NONE; - break; - default: - //usage(); - return -1; - } - } - - if (optind < argc) - input = argv[optind]; - - if (input == NULL || !strcmp(input, "-")) - buffer = file_read_to_buffer(STDIN_FILENO, &size); - else { - printf("Reading from %s\n", input); - buffer = file_read(input, &size); - } - - if (!iself(buffer)) { - fprintf(stderr, "E: This does not appear to be an ELF file\n"); - return -1; - } - - switch (algo) { - case CBFS_COMPRESS_NONE: - compress = none_compress; - break; - case CBFS_COMPRESS_LZMA: - compress = lzma_compress; - break; - default: - fprintf(stderr, "E: Unknown compression algorithm %d!\n", algo); - return -1; - } - - osize = parse_elf(buffer, &obuffer, algo, compress); - - if (osize == -1) { - fprintf(stderr, "E: Error while converting the payload\n"); - return -1; - } - - if (output == NULL || !strcmp(output, "-")) - file_write_from_buffer(STDOUT_FILENO, obuffer, osize); - else - file_write(output, obuffer, osize); - - return 0; -} diff --git a/util/cbfstool/tools/cbfs-mkstage.c b/util/cbfstool/cbfs-mkstage.c similarity index 63% rename from util/cbfstool/tools/cbfs-mkstage.c rename to util/cbfstool/cbfs-mkstage.c index b85a8f99dc..693d7cc099 100644 --- a/util/cbfstool/tools/cbfs-mkstage.c +++ b/util/cbfstool/cbfs-mkstage.c @@ -2,6 +2,8 @@ * cbfs-mkstage * * Copyright (C) 2008 Jordan Crouse + * 2009 coresystems GmbH + * written by Patrick Georgi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,7 +29,7 @@ #include #include "common.h" -#include "../cbfs.h" +#include "cbfs.h" unsigned int idemp(unsigned int x) { @@ -36,13 +38,15 @@ unsigned int idemp(unsigned int x) unsigned int swap32(unsigned int x) { - return ((x>>24) | ((x>>8) & 0xff00) | ((x<<8) & 0xff0000) | (x<<24)); + return ((x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | + (x << 24)); } -unsigned int (*elf32_to_native)(unsigned int)=idemp; +unsigned int (*elf32_to_native) (unsigned int) = idemp; -int parse_elf(unsigned char *input, unsigned char **output, - int mode, void (*compress) (char *, int, char *, int *)) +/* returns size of result, or -1 if error */ +int parse_elf_to_stage(unsigned char *input, unsigned char **output, + comp_algo algo, uint32_t * location) { Elf32_Phdr *phdr; Elf32_Ehdr *ehdr = (Elf32_Ehdr *) input; @@ -56,10 +60,22 @@ int parse_elf(unsigned char *input, unsigned char **output, int elf_bigendian = 0; int host_bigendian = 0; - if (ehdr->e_ident[EI_DATA]==ELFDATA2MSB) { + + comp_func_ptr compress = compression_function(algo); + if (!compress) + return -1; + + if (!iself(input)) { + fprintf(stderr, "E: The incoming file is not an ELF\n"); + return -1; + } + + if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) { elf_bigendian = 1; } - if ((unsigned int)"1234"==0x31323334) { + char test[4] = "1234"; + uint32_t inttest = *(uint32_t *) test; + if (inttest == 0x31323334) { host_bigendian = 1; } if (elf_bigendian != host_bigendian) { @@ -125,7 +141,8 @@ int parse_elf(unsigned char *input, unsigned char **output, continue; memcpy(buffer + (elf32_to_native(phdr[i].p_paddr) - data_start), - &header[elf32_to_native(phdr[i].p_offset)], elf32_to_native(phdr[i].p_filesz)); + &header[elf32_to_native(phdr[i].p_offset)], + elf32_to_native(phdr[i].p_filesz)); } /* Now make the output buffer */ @@ -140,92 +157,15 @@ int parse_elf(unsigned char *input, unsigned char **output, stage->load = data_start; stage->memlen = mem_end - data_start; - stage->compression = mode; + stage->compression = algo; stage->entry = ehdr->e_entry; compress(buffer, data_end - data_start, - (char *)(out + sizeof(struct cbfs_stage)), - (int *)&stage->len); + (char *)(out + sizeof(struct cbfs_stage)), (int *)&stage->len); *output = out; + if (*location) + *location -= sizeof(struct cbfs_stage); return sizeof(struct cbfs_stage) + stage->len; } - -int main(int argc, char **argv) -{ - void (*compress) (char *, int, char *, int *); - int algo = CBFS_COMPRESS_LZMA; - - char *output = NULL; - char *input = NULL; - - unsigned char *buffer, *obuffer; - int size, osize; - - while (1) { - int option_index; - static struct option longopt[] = { - {"output", 1, 0, 'o'}, - {"lzma", 0, 0, 'l'}, - {"nocompress", 0, 0, 'n'}, - }; - - signed char ch = getopt_long(argc, argv, "o:ln", - longopt, &option_index); - - if (ch == -1) - break; - - switch (ch) { - case 'o': - output = optarg; - break; - case 'l': - algo = CBFS_COMPRESS_LZMA; - break; - case 'n': - algo = CBFS_COMPRESS_NONE; - break; - default: - //usage(); - return -1; - } - } - - if (optind < argc) - input = argv[optind]; - - if (input == NULL || !strcmp(input, "-")) - buffer = file_read_to_buffer(STDIN_FILENO, &size); - else - buffer = file_read(input, &size); - - if (!iself(buffer)) { - fprintf(stderr, "E: The incoming file is not an ELF\n"); - return -1; - } - - switch (algo) { - case CBFS_COMPRESS_NONE: - compress = none_compress; - break; - case CBFS_COMPRESS_LZMA: - compress = lzma_compress; - break; - } - - osize = parse_elf(buffer, &obuffer, algo, compress); - - if (osize == -1) { - fprintf(stderr, "E: Error while converting the ELF\n"); - return -1; - } - - if (output == NULL || !strcmp(output, "-")) - file_write_from_buffer(STDOUT_FILENO, obuffer, osize); - else - file_write(output, obuffer, osize); - - return 0; -} diff --git a/util/cbfstool/cbfs.h b/util/cbfstool/cbfs.h index 04a12fc24a..9d57165d85 100644 --- a/util/cbfstool/cbfs.h +++ b/util/cbfstool/cbfs.h @@ -1,7 +1,6 @@ /* - * cbfstool - * - * Copyright (C) 2008 Jordan Crouse + * Copyright (C) 2009 coresystems GmbH + * written by Patrick Georgi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,17 +16,52 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA */ -#ifndef _CBFS_H_ -#define _CBFS_H_ +#include -/** These are standard values for the known compression - alogrithms that coreboot knows about for stages and - payloads. Of course, other LAR users can use whatever - values they want, as long as they understand them. */ +struct cbfs_header { + uint32_t magic; + uint32_t version; + uint32_t romsize; + uint32_t bootblocksize; + uint32_t align; + uint32_t offset; + uint32_t pad[2]; +} __attribute__ ((packed)); -#define CBFS_COMPRESS_NONE 0 -#define CBFS_COMPRESS_LZMA 1 -#define CBFS_COMPRESS_NRV2B 2 +struct cbfs_file { + char magic[8]; + uint32_t len; + uint32_t type; + uint32_t checksum; + uint32_t offset; +} __attribute__ ((packed)); + +struct cbfs_stage { + unsigned int compression; + unsigned long long entry; + unsigned long long load; + unsigned int len; + unsigned int memlen; +} __attribute__ ((packed)); + +#define PAYLOAD_SEGMENT_CODE 0x45444F43 +#define PAYLOAD_SEGMENT_DATA 0x41544144 +#define PAYLOAD_SEGMENT_BSS 0x20535342 +#define PAYLOAD_SEGMENT_PARAMS 0x41524150 +#define PAYLOAD_SEGMENT_ENTRY 0x52544E45 + +struct cbfs_payload_segment { + unsigned int type; + unsigned int compression; + unsigned int offset; + unsigned long long load_addr; + unsigned int len; + unsigned int mem_len; +} __attribute__ ((packed)); + +struct cbfs_payload { + struct cbfs_payload_segment segments; +} __attribute__ ((packed)); /** These are standard component types for well known components (i.e - those that coreboot needs to consume. @@ -50,90 +84,5 @@ */ #define CBFS_COMPONENT_NULL 0xFFFFFFFF -/** this is the master cbfs header - it need to be - located somewhere in the bootblock. Where it - actually lives is up to coreboot. A pointer to - this header will live at 0xFFFFFFF4, so we can - easily find it. */ - -#define HEADER_MAGIC 0x4F524243 - -/* this is a version that gives the right answer in any endian-ness */ -#define VERSION1 0x31313131 - -struct cbfs_header { - unsigned int magic; - unsigned int version; - unsigned int romsize; - unsigned int bootblocksize; - unsigned int align; - unsigned int offset; - unsigned int pad[2]; -} __attribute__ ((packed)); - -/** This is a component header - every entry in the CBFS - will have this header. - - This is how the component is arranged in the ROM: - - -------------- <- 0 - component header - -------------- <- sizeof(struct component) - component name - -------------- <- offset - data - ... - -------------- <- offset + len -*/ - -#define COMPONENT_MAGIC "LARCHIVE" - -struct cbfs_file { - char magic[8]; - unsigned int len; - unsigned int type; - unsigned int checksum; - unsigned int offset; -} __attribute__ ((packed)); - -/*** Component sub-headers ***/ - -/* Following are component sub-headers for the "standard" - component types */ - -/** This is the sub-header for stage components. Stages are - loaded by coreboot during the normal boot process */ - -struct cbfs_stage { - unsigned int compression; /** Compression type */ - unsigned long long entry; /** entry point */ - unsigned long long load; /** Where to load in memory */ - unsigned int len; /** length of data to load */ - unsigned int memlen; /** total length of object in memory */ -} __attribute__ ((packed)); - -/** this is the sub-header for payload components. Payloads - are loaded by coreboot at the end of the boot process */ - -struct cbfs_payload_segment { - unsigned int type; - unsigned int compression; - unsigned int offset; - unsigned long long load_addr; - unsigned int len; - unsigned int mem_len; -} __attribute__ ((packed)); - -struct cbfs_payload { - struct cbfs_payload_segment segments; -}; - -#define PAYLOAD_SEGMENT_CODE 0x45444F43 -#define PAYLOAD_SEGMENT_DATA 0x41544144 -#define PAYLOAD_SEGMENT_BSS 0x20535342 -#define PAYLOAD_SEGMENT_PARAMS 0x41524150 -#define PAYLOAD_SEGMENT_ENTRY 0x52544E45 - -#define CBFS_NAME(_c) (((unsigned char *) (_c)) + sizeof(struct cbfs_file)) - -#endif +int cbfs_file_header(uint32_t physaddr); +struct cbfs_file *cbfs_create_empty_file(uint32_t physaddr, uint32_t size); diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c index 7760a56109..637bddb1fc 100644 --- a/util/cbfstool/cbfstool.c +++ b/util/cbfstool/cbfstool.c @@ -1,7 +1,8 @@ /* - * cbfstool + * cbfstool, CLI utility for CBFS file manipulation * - * Copyright (C) 2008 Jordan Crouse + * Copyright (C) 2009 coresystems GmbH + * written by Patrick Georgi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,145 +18,116 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA */ -/* v2 compat: First, assumes a 64K bootblock. - * cbfstool coreboot.rom create 0x80000 coreboot.strip - * cbfstool coreboot.rom add-payload /tmp/filo.elf payload - * cbfstool coreboot.rom extract new_filo.elf payload - * cbfstool coreboot.rom print - */ - - -#include -#include -#include -#include -#include "cbfstool.h" - -extern int create_handler(struct rom *, int, char **); -extern int bootblock_handler(struct rom *, int, char **); -extern int print_handler(struct rom *, int, char **); -extern int add_handler(struct rom *, int, char **); -extern int extract_handler(struct rom *, int, char **); -extern int delete_handler(struct rom *, int, char **); -extern int resize_handler(struct rom *, int, char **); -extern int add_payload_handler(struct rom *, int, char **); -extern int add_stage_handler(struct rom *, int, char **); - -extern void create_usage(void); -extern void bootblock_usage(void); -extern void print_usage(void); -extern void add_usage(void); -extern void delete_usage(void); -extern void extract_usage(void); -extern void resize_usage(void); -extern void add_payload_usage(void); -extern void add_stage_usage(void); - -struct { - char *command; - int (*handler) (struct rom *, int, char **); - void (*help) (void); -} commands[] = { - { - "add", add_handler, add_usage}, { - "add-payload", add_payload_handler, add_payload_usage}, { - "add-stage", add_stage_handler, add_stage_usage}, { - "bootblock", bootblock_handler, bootblock_usage}, { - "create", create_handler, create_usage}, { - "delete", delete_handler, delete_usage}, { - "extract", extract_handler, extract_usage}, { - "print", print_handler, print_usage}, { - "resize", resize_handler, resize_usage}, { -"", NULL, NULL},}; - -static struct rom rom; - -char cbfstool_bindir[255]; - -void show_help(void) -{ - int i; - - printf("cbfstool [OPTION] [[FILE] [COMMAND] [PARAMETERS]...\n"); - printf("Apply COMMANDS with PARAMETERS to FILE. If no COMMAND is\n"); - printf("given, run in interactive mode\n\n"); - printf("OPTIONs:\n"); - printf(" -h\t\tDisplay this help message\n"); - printf(" -C \tChange to the directory before operating\n\n"); - printf("COMMANDs:\n"); - - for (i = 0; commands[i].handler != NULL; i++) - commands[i].help(); -} +#include +#include +#include "common.h" +#include "cbfs.h" int main(int argc, char **argv) { - char *cdir = NULL; - char *rname; - char *cmd; - int ret = -1, i; + if (argc < 3) { + printf + ("cbfstool: Management utility for CBFS formatted ROM images\n" + "USAGE:\n" "cbfstool [-h]\n" + "cbfstool FILE COMMAND [PARAMETERS]...\n\n" "OPTIONs:\n" + " -h Display this help message\n\n" + "COMMANDs:\n" + "add FILE NAME TYPE [base address] Add a component\n" + "add-payload FILE NAME [COMP] [base] Add a payload to the ROM\n" + "add-stage FILE NAME [COMP] [base] Add a stage to the ROM\n" + "create SIZE BSIZE BOOTBLOCK [ALIGN] Create a ROM file\n" + "print Show the contents of the ROM\n"); + return 1; + } + char *romname = argv[1]; + char *cmd = argv[2]; - strncpy(cbfstool_bindir, dirname(argv[0]), 254); - - while (1) { - signed ch = getopt(argc, argv, "hC:"); - if (ch == -1) - break; - switch (ch) { - case 'h': - show_help(); - return -1; - case 'C': - cdir = optarg; - break; + if (strcmp(cmd, "create") == 0) { + if (argc < 6) { + printf("not enough arguments to 'create'.\n"); + return 1; } + uint32_t size = strtoul(argv[3], NULL, 0); + /* ignore bootblock size. we use whatever we get and won't allocate any larger */ + char *bootblock = argv[5]; + uint32_t align = 0; + if (argc > 6) + align = strtoul(argv[6], NULL, 0); + return create_cbfs_image(romname, size, bootblock, align); } - if (optind >= argc) { - show_help(); - return -1; + void *rom = loadrom(romname); + + if (strcmp(cmd, "print") == 0) { + print_cbfs_directory(romname); + return 0; } - if (cdir != NULL && chdir(cdir)) { - ERROR("Unable to switch to %s: %m\n", cdir); - return -1; + if (argc < 5) { + printf("not enough arguments to '%s'.\n", cmd); + return 1; } - rname = argv[optind]; - cmd = optind + 1 < argc ? argv[optind + 1] : NULL; + void *filename = argv[3]; + void *cbfsname = argv[4]; - /* Open the ROM (if it exists) */ - rom.name = (unsigned char *)strdup(rname); + uint32_t filesize = 0; + void *filedata = loadfile(filename, &filesize, 0, SEEK_SET); - if (!access(rname, F_OK)) { - if (open_rom(&rom, rname)) { - ERROR("Problem while reading the ROM\n"); - return -1; + uint32_t base = 0; + void *cbfsfile; + + if (strcmp(cmd, "add") == 0) { + if (argc < 6) { + printf("not enough arguments to 'add'.\n"); + return 1; } - } - - if (cmd) { - /* Process the incoming comand */ - - for (i = 0; commands[i].handler != NULL; i++) { - if (!strcmp(commands[i].command, cmd)) { - ret = commands[i].handler(&rom, - argc - 3, &argv[3]); - goto leave; - } + uint32_t type; + if (intfiletype(argv[5]) != ((uint64_t) - 1)) + type = intfiletype(argv[5]); + else + type = strtoul(argv[5], NULL, 0); + if (argc > 6) { + base = strtoul(argv[6], NULL, 0); } - - ERROR("Command %s not valid\n", cmd); - } else { - printf("Interactive mode not ready yet!\n"); + cbfsfile = + create_cbfs_file(cbfsname, filedata, &filesize, type, + &base); } -leave: - if (rom.ptr != NULL && rom.ptr != MAP_FAILED) - munmap(rom.ptr, rom.size); + if (strcmp(cmd, "add-payload") == 0) { + comp_algo algo = CBFS_COMPRESS_NONE; + if (argc > 5) { + if (argv[5][0] == 'l') + algo = CBFS_COMPRESS_LZMA; + } + if (argc > 6) { + base = strtoul(argv[6], NULL, 0); + } + unsigned char *payload; + filesize = parse_elf_to_payload(filedata, &payload, algo); + cbfsfile = + create_cbfs_file(cbfsname, payload, &filesize, + CBFS_COMPONENT_PAYLOAD, &base); + } - if (rom.fd > 0) - close(rom.fd); + if (strcmp(cmd, "add-stage") == 0) { + comp_algo algo = CBFS_COMPRESS_NONE; + if (argc > 5) { + if (argv[5][0] == 'l') + algo = CBFS_COMPRESS_LZMA; + } + if (argc > 6) { + base = strtoul(argv[6], NULL, 0); + } + unsigned char *stage; + filesize = parse_elf_to_stage(filedata, &stage, algo, &base); + cbfsfile = + create_cbfs_file(cbfsname, stage, &filesize, + CBFS_COMPONENT_STAGE, &base); + } - return ret; + add_file_to_cbfs(cbfsfile, filesize, base); + writerom(romname, rom, romsize); + return 0; } diff --git a/util/cbfstool/cbfstool.h b/util/cbfstool/cbfstool.h deleted file mode 100644 index adfa9d0f31..0000000000 --- a/util/cbfstool/cbfstool.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * cbfstool - * - * Copyright (C) 2008 Jordan Crouse - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -#ifndef _ROMTOOL_H_ -#define _ROMTOOL_H_ - -#include -#include -#include "cbfs.h" - -/* Definitions */ - -/* Structures */ - -struct rom { - unsigned char *name; - unsigned char *ptr; - /* this will *almost* *always* be 0-rom->size, save for some really - * misdesigned systems (which have existed) - */ - unsigned long rombase; - - int fd; - int size; - int fssize; - - struct cbfs_header *header; -}; - -/* Macros */ - -#define ROM_OFFSET(_r, _c) ((unsigned int) ((unsigned char *) (_c) - (_r)->ptr)) - -#define ROM_PTR(_r, _o) ((_r)->ptr + (_o)) -#define ROM_WRITEL(_r, _o, _v) do { *((unsigned int *) ROM_PTR((_r), (_o))) = (_v); } while(0) -#define ROM_READL(_r, _o) *((unsigned int *) (ROM_PTR((_r), (_o)))) - -#define ERROR(err, args...) fprintf(stderr, "(cbfstool) E: " err, ##args) -#define WARN(err, args...) fprintf(stderr, "(cbfstool) W: " err, ##args) -#define VERBOSE(str, args...) printf(str, ##args) - -#define TRUNCATE(_v, _a) ( (_v) & ~( (_a) - 1 ) ) -#define ALIGN(_v, _a) ( ( (_v) + ( (_a) - 1 ) ) & ~( (_a) - 1 ) ) - -/* Function prototypes */ - -/* util.c */ -void flashinit(void *ptr, size_t len); -int open_rom(struct rom *rom, const char *filename); -int create_rom(struct rom *rom, const unsigned char *filename, int size, - const char *bootblockname, int bootblocksize, - int align); -int size_and_open(const char *filename, unsigned int *size); -int copy_from_fd(int fd, void *ptr, int size); -int get_size(const char *size); -int add_bootblock(struct rom *rom, const char *filename); - -/* fs.c */ - -struct cbfs_file *rom_find(struct rom *rom, int offset); -struct cbfs_file *rom_find_first(struct rom *); -struct cbfs_file *rom_find_next(struct rom *, struct cbfs_file *); -int rom_add(struct rom *rom, const char *name, void *, unsigned long address, int size, int type); -int rom_set_header(struct rom *rom, struct cbfs_file *c, - const char*name, int size, int type); -int rom_extract(struct rom *rom, const char *name, void **buf, int *size); -int rom_remove(struct rom *rom, const char *name); -int rom_used_space(struct rom *rom); -int rom_exists(struct rom *rom); - -#endif diff --git a/util/cbfstool/common.c b/util/cbfstool/common.c new file mode 100644 index 0000000000..8db2d8cfe3 --- /dev/null +++ b/util/cbfstool/common.c @@ -0,0 +1,298 @@ +/* + * common utility functions for cbfstool + * + * Copyright (C) 2009 coresystems GmbH + * written by Patrick Georgi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA + */ + +#include +#include +#include +#include "common.h" +#include "cbfs.h" +#include "elf.h" + +#define dprintf + +void *loadfile(const char *filename, uint32_t * romsize_p, void *content, + int place) +{ + FILE *file = fopen(filename, "rb"); + fseek(file, 0, SEEK_END); + *romsize_p = ftell(file); + fseek(file, 0, SEEK_SET); + if (!content) + content = malloc(*romsize_p); + else if (place == SEEK_END) + content -= *romsize_p; + if (!fread(content, *romsize_p, 1, file)) { + printf("failed to read %s\n", filename); + return NULL; + } + fclose(file); + return content; +} + +struct cbfs_header *master_header; +uint32_t phys_start, phys_end, align, romsize; +void *offset; + +void recalculate_rom_geometry(void *romarea) +{ + offset = romarea + romsize - 0x100000000ULL; + master_header = (struct cbfs_header *) + phys_to_virt(*((uint32_t *) phys_to_virt(0xfffffffc))); + phys_start = (0 - romsize + ntohl(master_header->offset)) & 0xffffffff; + phys_end = + (0 - ntohl(master_header->bootblocksize) - + sizeof(struct cbfs_header)) & 0xffffffff; + align = ntohl(master_header->align); +} + +void *loadrom(const char *filename) +{ + void *romarea = loadfile(filename, &romsize, 0, SEEK_SET); + recalculate_rom_geometry(romarea); + return romarea; +} + +void writerom(const char *filename, void *start, uint32_t size) +{ + FILE *file = fopen(filename, "wb"); + fwrite(start, size, 1, file); + fclose(file); +} + +int cbfs_file_header(uint32_t physaddr) +{ + /* maybe improve this test */ + return (strncmp(phys_to_virt(physaddr), "LARCHIVE", 8) == 0); +} + +struct cbfs_file *cbfs_create_empty_file(uint32_t physaddr, uint32_t size) +{ + struct cbfs_file *nextfile = (struct cbfs_file *)phys_to_virt(physaddr); + strncpy(nextfile->magic, "LARCHIVE", 8); + nextfile->len = htonl(size); + nextfile->type = htonl(0xffffffff); + nextfile->checksum = 0; // FIXME? + nextfile->offset = htonl(sizeof(struct cbfs_file) + 16); + memset(((void *)nextfile) + sizeof(struct cbfs_file), 0, 16); + return nextfile; +} + +int iself(unsigned char *input) +{ + Elf32_Ehdr *ehdr = (Elf32_Ehdr *) input; + return !memcmp(ehdr->e_ident, ELFMAG, 4); +} + +struct filetypes_t { + uint32_t type; + const char *name; +} filetypes[] = { + {CBFS_COMPONENT_STAGE, "stage"}, + {CBFS_COMPONENT_PAYLOAD, "payload"}, + {CBFS_COMPONENT_OPTIONROM, "optionrom"}, + {CBFS_COMPONENT_DELETED, "deleted"}, + {CBFS_COMPONENT_NULL, "null"} +}; + +const char *strfiletype(uint32_t number) +{ + int i; + for (i = 0; i < (sizeof(filetypes) / sizeof(struct filetypes_t)); i++) + if (filetypes[i].type == number) + return filetypes[i].name; + return "unknown"; +} + +uint64_t intfiletype(const char *name) +{ + int i; + for (i = 0; i < (sizeof(filetypes) / sizeof(struct filetypes_t)); i++) + if (strcmp(filetypes[i].name, name) == 0) + return filetypes[i].type; + return -1; +} + +void print_cbfs_directory(const char *filename) +{ + printf + ("%s: %d kB, bootblocksize %d, romsize %d, offset 0x%x\nAlignment: %d bytes\n\n", + filename, romsize / 1024, ntohl(master_header->bootblocksize), + romsize, ntohl(master_header->offset), align); + printf("%-30s %-10s %-12s Size\n", "Name", "Offset", "Type"); + uint32_t current = phys_start; + while (current < phys_end) { + if (!cbfs_file_header(current)) { + current += align; + continue; + } + struct cbfs_file *thisfile = + (struct cbfs_file *)phys_to_virt(current); + uint32_t length = ntohl(thisfile->len); + printf("%-30s 0x%-8x %-12s %d\n", + (const char *)(phys_to_virt(current) + + sizeof(struct cbfs_file)), + current - phys_start, strfiletype(ntohl(thisfile->type)), + length); + current = + ALIGN(current + ntohl(thisfile->len) + + ntohl(thisfile->offset), align); + } +} + +int add_file_to_cbfs(void *content, uint32_t contentsize, uint32_t location) +{ + uint32_t current = phys_start; + while (current < phys_end) { + if (!cbfs_file_header(current)) { + current += align; + continue; + } + struct cbfs_file *thisfile = + (struct cbfs_file *)phys_to_virt(current); + uint32_t length = ntohl(thisfile->len); + + dprintf("at %x, %x bytes\n", current, length); + /* Is this a free chunk? */ + if ((thisfile->type == CBFS_COMPONENT_DELETED) + || (thisfile->type == CBFS_COMPONENT_NULL)) { + dprintf("null||deleted at %x, %x bytes\n", current, + length); + /* if this is the right size, and if specified, the right location, use it */ + if ((contentsize <= length) + && ((location == 0) || (current == location))) { + if (contentsize < length) { + dprintf + ("this chunk is %x bytes, we need %x. create a new chunk at %x with %x bytes\n", + length, contentsize, + ALIGN(current + contentsize, + align), + length - contentsize); + uint32_t start = + ALIGN(current + contentsize, align); + uint32_t size = + current + ntohl(thisfile->offset) + + length - start - 16 - + sizeof(struct cbfs_file); + cbfs_create_empty_file(start, size); + } + dprintf("copying data\n"); + memcpy(phys_to_virt(current), content, + contentsize); + break; + } + if (location == 0) + continue; + + /* CBFS has the constraint that the chain always moves up in memory. so once + we're past the place we seek, we don't need to look any further */ + if (current > location) { + printf + ("the requested space is not available\n"); + return 1; + } + + /* Is the requested location inside the current chunk? */ + if ((current < location) + && ((location + contentsize) <= (current + length))) { + /* Split it up. In the next iteration the code will be at the right place. */ + dprintf("split up. new length: %x\n", + location - current - + ntohl(thisfile->offset)); + thisfile->len = + htonl(location - current - + ntohl(thisfile->offset)); + struct cbfs_file *nextfile = + cbfs_create_empty_file(location, + length - (location - + current)); + } + } + current = + ALIGN(current + ntohl(thisfile->len) + + ntohl(thisfile->offset), align); + } + return 0; +} + +/* returns new data block with cbfs_file header, suitable to dump into the ROM. location returns + the new location that points to the cbfs_file header */ +void *create_cbfs_file(const char *filename, void *data, uint32_t * datasize, + uint32_t type, uint32_t * location) +{ + uint32_t filename_len = ALIGN(strlen(filename) + 1, 16); + uint32_t headersize = sizeof(struct cbfs_file) + filename_len; + if ((location != 0) && (*location != 0)) { + uint32_t offset = *location % align; + /* If offset >= (headersize % align), we can stuff the header into the offset. + Otherwise the header has to be aligned itself, and put before the offset data */ + if (offset >= (headersize % align)) { + offset -= (headersize % align); + } else { + offset += align - (headersize % align); + } + headersize += offset; + *location -= headersize; + } + void *newdata = malloc(*datasize + headersize); + struct cbfs_file *nextfile = (struct cbfs_file *)newdata; + strncpy(nextfile->magic, "LARCHIVE", 8); + nextfile->len = htonl(*datasize); + nextfile->type = htonl(type); + nextfile->checksum = 0; // FIXME? + nextfile->offset = htonl(headersize); + strcpy(newdata + sizeof(struct cbfs_file), filename); + memcpy(newdata + headersize, data, *datasize); + *datasize += headersize; + return newdata; +} + +int create_cbfs_image(const char *romfile, uint32_t _romsize, + const char *bootblock, uint32_t align) +{ + romsize = _romsize; + unsigned char *romarea = malloc(romsize); + memset(romarea, 0xff, romsize); + recalculate_rom_geometry(romarea); + + if (align == 0) + align = 64; + + uint32_t bootblocksize = 0; + loadfile(bootblock, &bootblocksize, romarea + romsize, SEEK_END); + struct cbfs_header *master_header = + (struct cbfs_header *)(romarea + romsize - bootblocksize - + sizeof(struct cbfs_header)); + master_header->magic = ntohl(0x4f524243); + master_header->version = ntohl(0x31313131); + master_header->romsize = htonl(romsize); + master_header->bootblocksize = htonl(bootblocksize); + master_header->align = htonl(align); + master_header->offset = htonl(0); + ((uint32_t *) phys_to_virt(0xfffffffc))[0] = + virt_to_phys(master_header); + struct cbfs_file *one_empty_file = + cbfs_create_empty_file((0 - romsize) & 0xffffffff, + romsize - bootblocksize - + sizeof(struct cbfs_header) - + sizeof(struct cbfs_file) - 16); + + writerom(romfile, romarea, romsize); + return 0; +} diff --git a/util/cbfstool/common.h b/util/cbfstool/common.h new file mode 100644 index 0000000000..944f215b5d --- /dev/null +++ b/util/cbfstool/common.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2009 coresystems GmbH + * written by Patrick Georgi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA + */ + +#include + +extern void *offset; +extern struct cbfs_header *master_header; +extern uint32_t phys_start, phys_end, align, romsize; + +static void *phys_to_virt(uint32_t addr) +{ + return offset + addr; +} + +static uint32_t virt_to_phys(void *addr) +{ + return (long)(addr - offset) & 0xffffffff; +} + +#define ALIGN(val, by) (((val) + (by)-1)&~((by)-1)) + +void *loadfile(const char *filename, uint32_t * romsize_p, void *content, + int place); +void *loadrom(const char *filename); +void writerom(const char *filename, void *start, uint32_t size); + +int iself(unsigned char *input); + +typedef void (*comp_func_ptr) (char *, int, char *, int *); +typedef enum { CBFS_COMPRESS_NONE = 0, CBFS_COMPRESS_LZMA = 1 } comp_algo; + +comp_func_ptr compression_function(comp_algo algo); + +uint64_t intfiletype(const char *name); + +int parse_elf_to_payload(unsigned char *input, unsigned char **output, + comp_algo algo); +int parse_elf_to_stage(unsigned char *input, unsigned char **output, + comp_algo algo, uint32_t * location); + +void *create_cbfs_file(const char *filename, void *data, uint32_t * datasize, + uint32_t type, uint32_t * location); + +int create_cbfs_image(const char *romfile, uint32_t romsize, + const char *bootblock, uint32_t align); + +int add_file_to_cbfs(void *content, uint32_t contentsize, uint32_t location); +void print_cbfs_directory(const char *filename); diff --git a/util/cbfstool/tools/compress.c b/util/cbfstool/compress.c similarity index 60% rename from util/cbfstool/tools/compress.c rename to util/cbfstool/compress.c index fb8fe82931..2222dab112 100644 --- a/util/cbfstool/tools/compress.c +++ b/util/cbfstool/compress.c @@ -1,7 +1,12 @@ /* - * cbfstool + * compression handling for cbfstool * - * Copyright (C) 2008 Jordan Crouse + * Copyright (C) 2009 coresystems GmbH + * written by Patrick Georgi + * + * Adapted from code + * Copyright (C) 2008 Jordan Crouse , released + * under identical license terms * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,6 +23,8 @@ */ #include +#include +#include "common.h" extern void do_lzma_compress(char *in, int in_len, char *out, int *out_len); @@ -31,3 +38,20 @@ void none_compress(char *in, int in_len, char *out, int *out_len) memcpy(out, in, in_len); *out_len = in_len; } + +comp_func_ptr compression_function(comp_algo algo) +{ + comp_func_ptr compress; + switch (algo) { + case CBFS_COMPRESS_NONE: + compress = none_compress; + break; + case CBFS_COMPRESS_LZMA: + compress = lzma_compress; + break; + default: + fprintf(stderr, "E: Unknown compression algorithm %d!\n", algo); + return NULL; + } + return compress; +} diff --git a/util/cbfstool/create.c b/util/cbfstool/create.c deleted file mode 100644 index e83758c992..0000000000 --- a/util/cbfstool/create.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * cbfstool - * - * Copyright (C) 2008 Jordan Crouse - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -#include -#include -#include -#include "cbfstool.h" - -void create_usage(void) -{ - printf("create SIZE BOOTBLOCKSIZE BOOTBLOCK [ALIGN]\tCreate a ROM file\n"); -} - -int create_handler(struct rom *rom, int argc, char **argv) -{ - int align = 16, size; - char *bootblock = NULL; - int bootblocksize; - - if (argc < 3) { - create_usage(); - return -1; - } - - size = get_size(argv[0]); - - bootblocksize = get_size(argv[1]); - - bootblock = argv[2]; - - if (argc >= 4) { - align = strtoul(argv[3], NULL, 0); - } - - if (size < bootblocksize) { - ERROR("Cannot create a rom %d smaller then bootblock size %d\n", size, bootblocksize); - return -1; - } - - if (align == 0) { - ERROR("Cannot create with an align size of 0\n"); - return -1; - } - - if (create_rom(rom, rom->name, size, bootblock, bootblocksize, align)) - return -1; - - return 0; -} diff --git a/util/cbfstool/delete.c b/util/cbfstool/delete.c deleted file mode 100644 index 5185e83060..0000000000 --- a/util/cbfstool/delete.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * cbfstool - * - * Copyright (C) 2008 Jordan Crouse - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -#include -#include -#include -#include "cbfstool.h" - -void delete_usage(void) -{ - printf("delete [NAME] ...\t\tDelete a component\n"); -} - -int delete_handler(struct rom *rom, int argc, char **argv) -{ - int i; - int ret = 0; - - if (argc < 1) { - delete_usage(); - return -1; - } - - for (i = 0; i < argc; i++) - ret |= rom_remove(rom, argv[i]); - - return ret; -} diff --git a/util/cbfstool/tools/elf.h b/util/cbfstool/elf.h similarity index 100% rename from util/cbfstool/tools/elf.h rename to util/cbfstool/elf.h diff --git a/util/cbfstool/extract.c b/util/cbfstool/extract.c deleted file mode 100644 index 5a30553d29..0000000000 --- a/util/cbfstool/extract.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * cbfstool - * - * Copyright (C) 2009 Myles Watson - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include "cbfstool.h" - -static int extract_blob(struct rom *rom, const char *filename, const char *name) -{ - void *buf; - int fd, ret; - int size; - - ret = rom_extract(rom, name, &buf, &size); - - if (ret == -1) - return -1; - - fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); - - if (fd == -1) { - ERROR("Could not open %s: %m\n", filename); - return -1; - } - - if (write(fd, buf, size) != size) { - ERROR("Couldn't write %d bytes!\n", size); - ret = -1; - } - - close(fd); - - return ret; -} - -void extract_usage(void) -{ - printf("extract [FILE] [NAME] \textract a component\n"); -} - -int extract_handler(struct rom *rom, int argc, char **argv) -{ - if (argc < 2) { - extract_usage(); - return -1; - } - - if (!rom_exists(rom)) { - ERROR("Can't find the ROM!\n"); - return -1; - } - - return extract_blob(rom, argv[0], argv[1]); -} - diff --git a/util/cbfstool/fs.c b/util/cbfstool/fs.c deleted file mode 100644 index 611b8fc673..0000000000 --- a/util/cbfstool/fs.c +++ /dev/null @@ -1,479 +0,0 @@ -/* - * cbfstool - * - * Copyright (C) 2008 Jordan Crouse - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -#include -#include -#include "cbfstool.h" - -int namelen(const char *name) -{ - return ALIGN(strlen(name) + 1, 16); -} - -/** - * Given a name, return the header size for that name. - * @param name The name - * @returns The header size given that name - */ -int headersize(const char *name) -{ - return sizeof(struct cbfs_file) + namelen(name); -} - -/** - * Given a name, set it into the header in a standard way - * @param file the cbfs file - * @param name The name - */ -void setname(struct cbfs_file *file, const char *name) -{ - memset(CBFS_NAME(file), 0, namelen(name)); - strcpy((char *)CBFS_NAME(file), name); -} - -/** - * Given a name, size, and type, set them into the header in a standard way. - * Special case of size of -1: set the size to all of ROM - * @param rom The rom - * @param c The cbfs file - * @param name The name - * @param size The size - * @param type The type - * @returns Always 0 for now - */ -int rom_set_header(struct rom *rom, struct cbfs_file *c, const char *name, int size, int type) -{ - unsigned int csize; - csize = headersize(name); - - strcpy(c->magic, COMPONENT_MAGIC); - - /* special case -- if size is -1, means "as much as you can" - * it's usually only used in init. - */ - if (size < 0) - size = rom->fssize - csize; - c->len = htonl(size); - c->offset = htonl(csize); - c->type = htonl(type); - - setname(c, name); - return 0; -} - -int nextfile(struct rom *rom, struct cbfs_file *c, int offset) -{ - return ALIGN(offset + ntohl(c->len), - ntohl(rom->header->align)); -} - - -/* split - * split is a basic primitive in cbfs. Over time, it should be the main operator - * used to allocate space. For now for testing we are only using it in the - * fixed-address allocation. - * Split takes a cbfs_file and splits it into two pieces, as determined - * by the size of the file desired. Split only makes sense on CBFS_COMPONENT_NULL - * files -- splitting real files is an error, but no checking is done. - * @param file cbfs_file to split - * @param size Size of the file desired. - * @returns pointer to a cbfs_file stuct. - */ -static struct cbfs_file *split(struct rom *rom, struct cbfs_file *file, int size) -{ - struct cbfs_file *newfile = NULL; - unsigned long align = ntohl(rom->header->align); - unsigned long nextoffset, truncoffset; - unsigned long offset = ROM_OFFSET(rom, file); - /* figure out the real end of this file, and hence the size */ - /* compute where the next file is */ - nextoffset = ALIGN(offset + ntohl(file->len) + headersize(""), align); - /* compute where the end of this new file might be */ - truncoffset = ALIGN(offset + size + headersize(""), align); - /* If there is more than align bytes difference, create a new empty file */ - /* later, we can add code to merge all empty files. */ - if (nextoffset - truncoffset > align) { - unsigned int csize; - csize = headersize(""); - newfile = (struct cbfs_file *)ROM_PTR(rom, truncoffset); - rom_set_header(rom, newfile, "", - nextoffset - truncoffset - csize, CBFS_COMPONENT_NULL); - file->len = htonl(size); - } - return newfile; -} - - -/** - * rom_alloc_fixed - * Given a rom, walk the headers and find the first header of type - * CBFS_COMPONENT_NULL that is >= the desired size and - * contains the (address, length) desired. - * If the CBFS_COMPONENT_NULL is 'align' bytes > size, - * create a new header of CBFS_COMPONENT_NULL following the file. - * The 'len' structure member of the desired file is initialized, but - * nothing else is. - * Simple algorithm: walk until we find an empty file that contains our area, - * and then allocate out of it. - * @param rom The rom - * @param size the size of the file needed - * @returns pointer to a cbfs_file struct. - */ -struct cbfs_file * rom_alloc_fixed(struct rom *rom, const char *name, unsigned long start, unsigned long size, int type) -{ - /* walk the rom and find an empty file with a base > base, - * and a large enough size - */ - unsigned long base, end, alen, baseoff; - unsigned int offset = ntohl(rom->header->offset); - int ret = -1; - struct cbfs_file *c = NULL; - unsigned long align = ntohl(rom->header->align); - - /* compute a base that is aligned to align */ - base = TRUNCATE(start, align); - /* have to leave room for a header! */ - base -= headersize(name); - /* get an offset for that base */ - baseoff = base - rom->rombase; - end = ALIGN(start + size, align); - alen = end - base; - while (offset < rom->fssize) { - - c = (struct cbfs_file *)ROM_PTR(rom, offset); - - if (!strcmp(c->magic, COMPONENT_MAGIC)) { - if (c->type != CBFS_COMPONENT_NULL) { - offset += ALIGN(ntohl(c->offset) + ntohl(c->len), - align); - continue; - } - /* could turn this into a function. */ - /* is the start of this file < our desired start? */ - if (offset > baseoff) - break; - /* Is this file big enough for our needs? */ - if (ntohl(c->len) >= alen){ - ret = offset; - break; - } - offset += ALIGN(ntohl(c->offset) + ntohl(c->len), - align); - } else { - fprintf(stderr, "Corrupt rom -- found no header at %d\n", offset); - exit(1); - } - } - - if (ret < 0) - return NULL; - - /* we have the base offset of our location, and we have the offset for the file we are going to - * split. Split it. - */ - if (baseoff > offset) - c = split(rom, c, baseoff - offset - headersize("")); - /* split off anything left at the end that we don't need */ - split(rom, c, size); - - c->len = htonl(size); - - strcpy(c->magic, COMPONENT_MAGIC); - - c->offset = htonl(headersize(name)); - - c->type = htonl(type); - - setname(c, name); - - return ((struct cbfs_file *)ROM_PTR(rom, ret)); -} - - -/** - * rom_alloc - * Given a rom, walk the headers and find the first header of type - * CBFS_COMPONENT_NULL that is >= the desired size. - * If the CBFS_COMPONENT_NULL is 'align' bytes > size, - * create a new header of CBFS_COMPONENT_NULL following the file. - * The 'len' structure member of the desired file is initialized, but - * nothing else is. - * @param rom The rom - * @param size the size of the file needed - * @returns pointer to a cbfs_file struct. - */ -struct cbfs_file * rom_alloc(struct rom *rom, const char *name, unsigned long size, int type) -{ - /* walk the rom and find an empty file with a base > base, and a large enough size */ - unsigned int offset = ntohl(rom->header->offset); - int ret = -1; - struct cbfs_file *c = NULL; - unsigned long nextoffset, truncoffset; - struct cbfs_file *newfile = NULL; - - while ((offset + size) < rom->fssize) { - - c = (struct cbfs_file *)ROM_PTR(rom, offset); - - if (!strcmp(c->magic, COMPONENT_MAGIC)) { - if (c->type != CBFS_COMPONENT_NULL) { - offset += ALIGN(ntohl(c->offset) + ntohl(c->len), - ntohl(rom->header->align)); - continue; - } - /* Is this file big enough for our needs? */ - if (ntohl(c->len) >= size){ - ret = offset; - break; - } - offset += ALIGN(ntohl(c->offset) + ntohl(c->len), - ntohl(rom->header->align)); - } else { - fprintf(stderr, "Corrupt rom -- found no header at %d\n", offset); - exit(1); - } - } - - if (ret < 0) - return NULL; - - /* figure out the real end of this file, and hence the size */ - /* compute where the next file is */ - nextoffset = ALIGN(ret + ntohl(c->len) + headersize(name), - ntohl(rom->header->align)); - /* compute where the end of this new file might be */ - truncoffset = ALIGN(ret + size + headersize(name), - ntohl(rom->header->align)); - /* If there is more than align bytes difference, create a new empty file */ - /* later, we can add code to merge all empty files. */ - if (nextoffset - truncoffset > ntohl(rom->header->align)) { - unsigned int csize; - csize = headersize(""); - newfile = (struct cbfs_file *)ROM_PTR(rom, truncoffset); - rom_set_header(rom, newfile, "", - nextoffset - truncoffset - csize, CBFS_COMPONENT_NULL); - } else truncoffset = nextoffset; - - c->len = htonl(size); - - strcpy(c->magic, COMPONENT_MAGIC); - - c->offset = htonl(headersize(name)); - - c->type = htonl(type); - - setname(c, name); - - return ((struct cbfs_file *)ROM_PTR(rom, ret)); -} - -struct cbfs_file *rom_find(struct rom *rom, int offset) -{ - while (offset < rom->fssize) { - struct cbfs_file *c = - (struct cbfs_file *)ROM_PTR(rom, offset); - - if (!strcmp(c->magic, COMPONENT_MAGIC)) - return c; - - offset += ntohl(rom->header->align); - } - - return NULL; -} - -struct cbfs_file *rom_find_first(struct rom *rom) -{ - return rom_find(rom, ntohl(rom->header->offset)); -} - -struct cbfs_file *rom_find_next(struct rom *rom, struct cbfs_file *prev) -{ - unsigned int offset = ROM_OFFSET(rom, prev); - - return rom_find(rom, offset + - ALIGN(ntohl(prev->offset) + ntohl(prev->len), - ntohl(rom->header->align))); -} - -struct cbfs_file *rom_find_empty(struct rom *rom) -{ - unsigned int offset = ntohl(rom->header->offset); - unsigned int ret = ntohl(rom->header->offset); - - while (offset < rom->fssize) { - - struct cbfs_file *c = - (struct cbfs_file *)ROM_PTR(rom, offset); - - if (!strcmp(c->magic, COMPONENT_MAGIC)) { - offset += ALIGN(ntohl(c->offset) + ntohl(c->len), - ntohl(rom->header->align)); - - ret = offset; - } else - offset += ntohl(rom->header->align); - } - - return (ret < rom->fssize) ? - (struct cbfs_file *)ROM_PTR(rom, ret) : NULL; -} - -struct cbfs_file *rom_find_by_name(struct rom *rom, const char *name) -{ - struct cbfs_file *c = rom_find_first(rom); - - while (c) { - if (!strcmp((char *)CBFS_NAME(c), name)) - return c; - - c = rom_find_next(rom, c); - } - - return NULL; -} - -int rom_used_space(struct rom *rom) -{ - struct cbfs_file *c = rom_find_first(rom); - unsigned int ret = 0; - - while (c) { - int type; - type = ntohl(c->type); - if ((c->type == CBFS_COMPONENT_DELETED) || - (c->type == CBFS_COMPONENT_NULL)) - continue; - ret += ROM_OFFSET(rom, c) + ntohl(c->offset) + ntohl(c->len); - c = rom_find_next(rom, c); - } - - return ret; -} - -/** - * delete an item. This is a flash-friendly version -- it just blows the - * type to 0. Nothing else is changed. - * N.B. We no longer shuffle contents of ROM. That will come later. - * @param rom The rom - * @param name Name of file to remove. - * @return -1 on error, 0 if a file was set to deleted. - */ -int rom_remove(struct rom *rom, const char *name) -{ - struct cbfs_file *c = rom_find_by_name(rom, name); - - if (c == NULL) { - ERROR("Component %s does not exist\n", name); - return -1; - } - - c->type = CBFS_COMPONENT_DELETED; - - void *n = rom_find_next(rom, c); - int clear; - - if (n != NULL) { - memcpy(c, n, rom->fssize - ROM_OFFSET(rom, n)); - clear = ROM_OFFSET(rom, n) - ROM_OFFSET(rom, c); - } - else { /* No component after this one. */ - unsigned int csize; - csize = sizeof(struct cbfs_file) + ALIGN(strlen(name) + 1, 16); - clear = ntohl(c->len) + csize; - memcpy(c, ((void*)c) + clear, - rom->fssize - (ROM_OFFSET(rom, c)+clear)); - } - - /* Zero the new space, which is always at the end. */ - memset(ROM_PTR(rom, rom->fssize - clear), 0, clear); - - return 0; -} - -int rom_extract(struct rom *rom, const char *name, void** buf, int *size ) -{ - struct cbfs_file *c = rom_find_by_name(rom, name); - - if (c == NULL) { - ERROR("Component %s does not exist\n", name); - return -1; - } - - *size = ntohl(c->len); - *buf = ((unsigned char *)c) + headersize(name); - return 0; -} - -/** - * Add a new file named 'name', of type 'type', size 'size'. Initialize that file - * with the contents of 'buffer'. - * @param rom The rom - * @param name file name - * @param buffer file data - * @param address base address. 0 means 'whereever it fits' - * @param size Amount of data - * @param type File type - * @returns -1 on failure, 0 on success - */ -int rom_add(struct rom *rom, const char *name, void *buffer, unsigned long address, int size, int type) -{ - struct cbfs_file *c; - int csize; - - if (rom_find_by_name(rom, name)) { - ERROR("Component %s already exists in this rom\n", name); - return -1; - } - - if (address) - c = rom_alloc_fixed(rom, name, address, size, type); - else - c = rom_alloc(rom, name, size, type); - - if (c == NULL) { - ERROR("There is not enough room in this ROM\n"); - return -1; - } - - csize = sizeof(struct cbfs_file) + ALIGN(strlen(name) + 1, 16); - - int offset = ROM_OFFSET(rom, c); - - if (offset + csize + size > rom->fssize) { - ERROR("There is not enough room in this ROM for this\n"); - ERROR("component. I need %d bytes, only have %d bytes avail\n", - csize + size, rom->fssize - offset); - - return -1; - } - - strcpy(c->magic, COMPONENT_MAGIC); - - c->len = htonl(size); - c->offset = htonl(csize); - c->type = htonl(type); - - memset(CBFS_NAME(c), 0, ALIGN(strlen(name) + 1, 16)); - strcpy((char *)CBFS_NAME(c), name); - - memcpy(((unsigned char *)c) + csize, buffer, size); - return 0; -} - diff --git a/util/cbfstool/tools/lzma/C/7zip/Common/InBuffer.h b/util/cbfstool/lzma/C/7zip/Common/InBuffer.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Common/InBuffer.h rename to util/cbfstool/lzma/C/7zip/Common/InBuffer.h diff --git a/util/cbfstool/tools/lzma/C/7zip/Common/OutBuffer.cpp b/util/cbfstool/lzma/C/7zip/Common/OutBuffer.cpp similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Common/OutBuffer.cpp rename to util/cbfstool/lzma/C/7zip/Common/OutBuffer.cpp diff --git a/util/cbfstool/tools/lzma/C/7zip/Common/OutBuffer.h b/util/cbfstool/lzma/C/7zip/Common/OutBuffer.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Common/OutBuffer.h rename to util/cbfstool/lzma/C/7zip/Common/OutBuffer.h diff --git a/util/cbfstool/tools/lzma/C/7zip/Common/StdAfx.h b/util/cbfstool/lzma/C/7zip/Common/StdAfx.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Common/StdAfx.h rename to util/cbfstool/lzma/C/7zip/Common/StdAfx.h diff --git a/util/cbfstool/tools/lzma/C/7zip/Common/StreamUtils.cpp b/util/cbfstool/lzma/C/7zip/Common/StreamUtils.cpp similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Common/StreamUtils.cpp rename to util/cbfstool/lzma/C/7zip/Common/StreamUtils.cpp diff --git a/util/cbfstool/tools/lzma/C/7zip/Common/StreamUtils.h b/util/cbfstool/lzma/C/7zip/Common/StreamUtils.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Common/StreamUtils.h rename to util/cbfstool/lzma/C/7zip/Common/StreamUtils.h diff --git a/util/cbfstool/tools/lzma/C/7zip/Compress/LZ/BinTree/BinTree.h b/util/cbfstool/lzma/C/7zip/Compress/LZ/BinTree/BinTree.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Compress/LZ/BinTree/BinTree.h rename to util/cbfstool/lzma/C/7zip/Compress/LZ/BinTree/BinTree.h diff --git a/util/cbfstool/tools/lzma/C/7zip/Compress/LZ/BinTree/BinTree2.h b/util/cbfstool/lzma/C/7zip/Compress/LZ/BinTree/BinTree2.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Compress/LZ/BinTree/BinTree2.h rename to util/cbfstool/lzma/C/7zip/Compress/LZ/BinTree/BinTree2.h diff --git a/util/cbfstool/tools/lzma/C/7zip/Compress/LZ/BinTree/BinTree3.h b/util/cbfstool/lzma/C/7zip/Compress/LZ/BinTree/BinTree3.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Compress/LZ/BinTree/BinTree3.h rename to util/cbfstool/lzma/C/7zip/Compress/LZ/BinTree/BinTree3.h diff --git a/util/cbfstool/tools/lzma/C/7zip/Compress/LZ/BinTree/BinTree4.h b/util/cbfstool/lzma/C/7zip/Compress/LZ/BinTree/BinTree4.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Compress/LZ/BinTree/BinTree4.h rename to util/cbfstool/lzma/C/7zip/Compress/LZ/BinTree/BinTree4.h diff --git a/util/cbfstool/tools/lzma/C/7zip/Compress/LZ/BinTree/BinTreeMain.h b/util/cbfstool/lzma/C/7zip/Compress/LZ/BinTree/BinTreeMain.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Compress/LZ/BinTree/BinTreeMain.h rename to util/cbfstool/lzma/C/7zip/Compress/LZ/BinTree/BinTreeMain.h diff --git a/util/cbfstool/tools/lzma/C/7zip/Compress/LZ/HashChain/HC4.h b/util/cbfstool/lzma/C/7zip/Compress/LZ/HashChain/HC4.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Compress/LZ/HashChain/HC4.h rename to util/cbfstool/lzma/C/7zip/Compress/LZ/HashChain/HC4.h diff --git a/util/cbfstool/tools/lzma/C/7zip/Compress/LZ/HashChain/HCMain.h b/util/cbfstool/lzma/C/7zip/Compress/LZ/HashChain/HCMain.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Compress/LZ/HashChain/HCMain.h rename to util/cbfstool/lzma/C/7zip/Compress/LZ/HashChain/HCMain.h diff --git a/util/cbfstool/tools/lzma/C/7zip/Compress/LZ/IMatchFinder.h b/util/cbfstool/lzma/C/7zip/Compress/LZ/IMatchFinder.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Compress/LZ/IMatchFinder.h rename to util/cbfstool/lzma/C/7zip/Compress/LZ/IMatchFinder.h diff --git a/util/cbfstool/tools/lzma/C/7zip/Compress/LZ/LZInWindow.cpp b/util/cbfstool/lzma/C/7zip/Compress/LZ/LZInWindow.cpp similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Compress/LZ/LZInWindow.cpp rename to util/cbfstool/lzma/C/7zip/Compress/LZ/LZInWindow.cpp diff --git a/util/cbfstool/tools/lzma/C/7zip/Compress/LZ/LZInWindow.h b/util/cbfstool/lzma/C/7zip/Compress/LZ/LZInWindow.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Compress/LZ/LZInWindow.h rename to util/cbfstool/lzma/C/7zip/Compress/LZ/LZInWindow.h diff --git a/util/cbfstool/tools/lzma/C/7zip/Compress/LZ/StdAfx.h b/util/cbfstool/lzma/C/7zip/Compress/LZ/StdAfx.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Compress/LZ/StdAfx.h rename to util/cbfstool/lzma/C/7zip/Compress/LZ/StdAfx.h diff --git a/util/cbfstool/tools/lzma/C/7zip/Compress/LZMA/LZMA.h b/util/cbfstool/lzma/C/7zip/Compress/LZMA/LZMA.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Compress/LZMA/LZMA.h rename to util/cbfstool/lzma/C/7zip/Compress/LZMA/LZMA.h diff --git a/util/cbfstool/tools/lzma/C/7zip/Compress/LZMA/LZMAEncoder.cpp b/util/cbfstool/lzma/C/7zip/Compress/LZMA/LZMAEncoder.cpp similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Compress/LZMA/LZMAEncoder.cpp rename to util/cbfstool/lzma/C/7zip/Compress/LZMA/LZMAEncoder.cpp diff --git a/util/cbfstool/tools/lzma/C/7zip/Compress/LZMA/LZMAEncoder.h b/util/cbfstool/lzma/C/7zip/Compress/LZMA/LZMAEncoder.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Compress/LZMA/LZMAEncoder.h rename to util/cbfstool/lzma/C/7zip/Compress/LZMA/LZMAEncoder.h diff --git a/util/cbfstool/tools/lzma/C/7zip/Compress/LZMA/StdAfx.h b/util/cbfstool/lzma/C/7zip/Compress/LZMA/StdAfx.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Compress/LZMA/StdAfx.h rename to util/cbfstool/lzma/C/7zip/Compress/LZMA/StdAfx.h diff --git a/util/cbfstool/tools/lzma/C/7zip/Compress/RangeCoder/RangeCoder.h b/util/cbfstool/lzma/C/7zip/Compress/RangeCoder/RangeCoder.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Compress/RangeCoder/RangeCoder.h rename to util/cbfstool/lzma/C/7zip/Compress/RangeCoder/RangeCoder.h diff --git a/util/cbfstool/tools/lzma/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp b/util/cbfstool/lzma/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp rename to util/cbfstool/lzma/C/7zip/Compress/RangeCoder/RangeCoderBit.cpp diff --git a/util/cbfstool/tools/lzma/C/7zip/Compress/RangeCoder/RangeCoderBit.h b/util/cbfstool/lzma/C/7zip/Compress/RangeCoder/RangeCoderBit.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Compress/RangeCoder/RangeCoderBit.h rename to util/cbfstool/lzma/C/7zip/Compress/RangeCoder/RangeCoderBit.h diff --git a/util/cbfstool/tools/lzma/C/7zip/Compress/RangeCoder/RangeCoderBitTree.h b/util/cbfstool/lzma/C/7zip/Compress/RangeCoder/RangeCoderBitTree.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Compress/RangeCoder/RangeCoderBitTree.h rename to util/cbfstool/lzma/C/7zip/Compress/RangeCoder/RangeCoderBitTree.h diff --git a/util/cbfstool/tools/lzma/C/7zip/Compress/RangeCoder/RangeCoderOpt.h b/util/cbfstool/lzma/C/7zip/Compress/RangeCoder/RangeCoderOpt.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Compress/RangeCoder/RangeCoderOpt.h rename to util/cbfstool/lzma/C/7zip/Compress/RangeCoder/RangeCoderOpt.h diff --git a/util/cbfstool/tools/lzma/C/7zip/Compress/RangeCoder/StdAfx.h b/util/cbfstool/lzma/C/7zip/Compress/RangeCoder/StdAfx.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Compress/RangeCoder/StdAfx.h rename to util/cbfstool/lzma/C/7zip/Compress/RangeCoder/StdAfx.h diff --git a/util/cbfstool/tools/lzma/C/7zip/Decompress/LzmaDecode.c b/util/cbfstool/lzma/C/7zip/Decompress/LzmaDecode.c similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Decompress/LzmaDecode.c rename to util/cbfstool/lzma/C/7zip/Decompress/LzmaDecode.c diff --git a/util/cbfstool/tools/lzma/C/7zip/Decompress/LzmaDecode.h b/util/cbfstool/lzma/C/7zip/Decompress/LzmaDecode.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/Decompress/LzmaDecode.h rename to util/cbfstool/lzma/C/7zip/Decompress/LzmaDecode.h diff --git a/util/cbfstool/tools/lzma/C/7zip/ICoder.h b/util/cbfstool/lzma/C/7zip/ICoder.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/ICoder.h rename to util/cbfstool/lzma/C/7zip/ICoder.h diff --git a/util/cbfstool/tools/lzma/C/7zip/IStream.h b/util/cbfstool/lzma/C/7zip/IStream.h similarity index 100% rename from util/cbfstool/tools/lzma/C/7zip/IStream.h rename to util/cbfstool/lzma/C/7zip/IStream.h diff --git a/util/cbfstool/tools/lzma/C/Common/Alloc.cpp b/util/cbfstool/lzma/C/Common/Alloc.cpp similarity index 100% rename from util/cbfstool/tools/lzma/C/Common/Alloc.cpp rename to util/cbfstool/lzma/C/Common/Alloc.cpp diff --git a/util/cbfstool/tools/lzma/C/Common/Alloc.h b/util/cbfstool/lzma/C/Common/Alloc.h similarity index 100% rename from util/cbfstool/tools/lzma/C/Common/Alloc.h rename to util/cbfstool/lzma/C/Common/Alloc.h diff --git a/util/cbfstool/tools/lzma/C/Common/CRC.cpp b/util/cbfstool/lzma/C/Common/CRC.cpp similarity index 100% rename from util/cbfstool/tools/lzma/C/Common/CRC.cpp rename to util/cbfstool/lzma/C/Common/CRC.cpp diff --git a/util/cbfstool/tools/lzma/C/Common/CRC.h b/util/cbfstool/lzma/C/Common/CRC.h similarity index 100% rename from util/cbfstool/tools/lzma/C/Common/CRC.h rename to util/cbfstool/lzma/C/Common/CRC.h diff --git a/util/cbfstool/tools/lzma/C/Common/Defs.h b/util/cbfstool/lzma/C/Common/Defs.h similarity index 100% rename from util/cbfstool/tools/lzma/C/Common/Defs.h rename to util/cbfstool/lzma/C/Common/Defs.h diff --git a/util/cbfstool/tools/lzma/C/Common/MyCom.h b/util/cbfstool/lzma/C/Common/MyCom.h similarity index 100% rename from util/cbfstool/tools/lzma/C/Common/MyCom.h rename to util/cbfstool/lzma/C/Common/MyCom.h diff --git a/util/cbfstool/tools/lzma/C/Common/MyGuidDef.h b/util/cbfstool/lzma/C/Common/MyGuidDef.h similarity index 100% rename from util/cbfstool/tools/lzma/C/Common/MyGuidDef.h rename to util/cbfstool/lzma/C/Common/MyGuidDef.h diff --git a/util/cbfstool/tools/lzma/C/Common/MyInitGuid.h b/util/cbfstool/lzma/C/Common/MyInitGuid.h similarity index 100% rename from util/cbfstool/tools/lzma/C/Common/MyInitGuid.h rename to util/cbfstool/lzma/C/Common/MyInitGuid.h diff --git a/util/cbfstool/tools/lzma/C/Common/MyUnknown.h b/util/cbfstool/lzma/C/Common/MyUnknown.h similarity index 100% rename from util/cbfstool/tools/lzma/C/Common/MyUnknown.h rename to util/cbfstool/lzma/C/Common/MyUnknown.h diff --git a/util/cbfstool/tools/lzma/C/Common/MyWindows.h b/util/cbfstool/lzma/C/Common/MyWindows.h similarity index 100% rename from util/cbfstool/tools/lzma/C/Common/MyWindows.h rename to util/cbfstool/lzma/C/Common/MyWindows.h diff --git a/util/cbfstool/tools/lzma/C/Common/NewHandler.h b/util/cbfstool/lzma/C/Common/NewHandler.h similarity index 100% rename from util/cbfstool/tools/lzma/C/Common/NewHandler.h rename to util/cbfstool/lzma/C/Common/NewHandler.h diff --git a/util/cbfstool/tools/lzma/C/Common/StdAfx.h b/util/cbfstool/lzma/C/Common/StdAfx.h similarity index 100% rename from util/cbfstool/tools/lzma/C/Common/StdAfx.h rename to util/cbfstool/lzma/C/Common/StdAfx.h diff --git a/util/cbfstool/tools/lzma/C/Common/Types.h b/util/cbfstool/lzma/C/Common/Types.h similarity index 100% rename from util/cbfstool/tools/lzma/C/Common/Types.h rename to util/cbfstool/lzma/C/Common/Types.h diff --git a/util/cbfstool/tools/lzma/C/LGPL.txt b/util/cbfstool/lzma/C/LGPL.txt similarity index 100% rename from util/cbfstool/tools/lzma/C/LGPL.txt rename to util/cbfstool/lzma/C/LGPL.txt diff --git a/util/cbfstool/tools/lzma/C/ORIGIN b/util/cbfstool/lzma/C/ORIGIN similarity index 100% rename from util/cbfstool/tools/lzma/C/ORIGIN rename to util/cbfstool/lzma/C/ORIGIN diff --git a/util/cbfstool/tools/lzma/Makefile b/util/cbfstool/lzma/Makefile similarity index 100% rename from util/cbfstool/tools/lzma/Makefile rename to util/cbfstool/lzma/Makefile diff --git a/util/cbfstool/tools/lzma/Makefile.inc b/util/cbfstool/lzma/Makefile.inc similarity index 100% rename from util/cbfstool/tools/lzma/Makefile.inc rename to util/cbfstool/lzma/Makefile.inc diff --git a/util/cbfstool/tools/lzma/minilzma.cc b/util/cbfstool/lzma/minilzma.cc similarity index 100% rename from util/cbfstool/tools/lzma/minilzma.cc rename to util/cbfstool/lzma/minilzma.cc diff --git a/util/cbfstool/print.c b/util/cbfstool/print.c deleted file mode 100644 index 146c03f30a..0000000000 --- a/util/cbfstool/print.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * cbfstool - * - * Copyright (C) 2008 Jordan Crouse - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -#include -#include "cbfstool.h" - -void print_usage(void) -{ - printf("print\t\t\t\tShow the contents of the ROM\n"); -} - -int print_handler(struct rom *rom, int argc, char **argv) -{ - if ( argc > 0 ) { - ERROR("print %s? print takes no arguments.\n", argv[0]); - print_usage(); - return -1; - } - - printf("%s: %d kB, bootblocksize %d, romsize %d, offset 0x%x\n", rom->name, rom->size / 1024, - ntohl(rom->header->bootblocksize), ntohl(rom->header->romsize), ntohl(rom->header->offset)); - printf("Alignment: %d bytes\n\n", ntohl(rom->header->align)); - - struct cbfs_file *c = rom_find_first(rom); - - printf("%-30s Offset %-12s Size\n", "Name", "Type"); - - while (c) { - char type[12]; - - switch (htonl(c->type)) { - case CBFS_COMPONENT_STAGE: - strcpy(type, "stage"); - break; - case CBFS_COMPONENT_PAYLOAD: - strcpy(type, "payload"); - break; - case CBFS_COMPONENT_OPTIONROM: - strcpy(type, "optionrom"); - break; - case CBFS_COMPONENT_NULL: - strcpy(type, "free"); - break; - case CBFS_COMPONENT_DELETED: - strcpy(type, "deleted"); - break; - default: - sprintf(type, "0x%8.8x", htonl(c->type)); - break; - } - - printf("%-30s 0x%-8x %-12s %d\n", CBFS_NAME(c), - ROM_OFFSET(rom, c), type, htonl(c->len)); - - c = rom_find_next(rom, c); - } - - return 0; -} diff --git a/util/cbfstool/resize.c b/util/cbfstool/resize.c deleted file mode 100644 index ef3267f392..0000000000 --- a/util/cbfstool/resize.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * cbfstool - * - * Copyright (C) 2008 Jordan Crouse - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -#include -#include -#include -#include -#include - -#include "cbfstool.h" - -void resize_usage(void) -{ - printf("resize [SIZE] [ERASEBLOCK]\tResize the ROM\n"); -} - -int resize_handler(struct rom *rom, int argc, char **argv) -{ - unsigned int align, offset; - int size; - char null = '\0'; - int bootblocksize = ntohl(rom->header->bootblocksize); - - if (argc < 1) { - resize_usage(); - return -1; - } - - if (rom->fd <= 0) { - ERROR("ROM file %s does not exist\n", rom->name); - return -1; - } - - align = ntohl(rom->header->align); - size = get_size(argv[0]); - - if (argc >= 2) - align = strtoul(argv[1], NULL, 0); - - if (size == rom->size && align == ntohl(rom->header->align)) { - ERROR("New parameters are the same as the old\n"); - return 0; - } - - if (size < bootblocksize) { - ERROR("The new size is smaller then the bootblock size\n"); - return -1; - } - - /* if the current ROM is too big for the new size, then complain */ - - if (rom_used_space(rom) > size - bootblocksize) { - ERROR("The new size is too small for the current ROM\n"); - return -1; - } - - /* Grow the rom if we need to */ - - if (size > rom->size) { - munmap(rom->ptr, rom->size); - - lseek(rom->fd, size - 1, SEEK_SET); - write(rom->fd, &null, 1); - - rom->ptr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, - rom->fd, 0); - - if (rom->ptr == MAP_FAILED) { - ERROR("Unable to grow the ROM\n"); - return -1; - } - } - - /* We only have to rewrite the entries if the alignment changed */ - - if (align != ntohl(rom->header->align)) { - struct cbfs_file *c; - - /* The first entry doesn't have to move */ - - c = rom_find(rom, rom->header->offset); - - while (c) { - struct cbfs_file *n = rom_find_next(rom, c); - unsigned int next; - - if (n == NULL) - break; - - /* Calculate a new location for the entry */ - next = ROM_OFFSET(rom, c) + - ALIGN(ntohl(c->offset) + ntohl(c->len), align); - - /* Copy the next entry there */ - memmove(ROM_PTR(rom, next), n, - ntohl(n->offset) + ntohl(n->len)); - - c = (struct cbfs_file *)ROM_PTR(rom, next); - - /* If the previous header wasn't overwritten by - * the change, corrupt the header so we don't - * accidently find it - */ - - if (ROM_OFFSET(rom, n) > - next + ntohl(c->len) + ntohl(c->offset)) - memset(n->magic, 0, sizeof(n->magic)); - } - } - - /* Copy the bootblock */ - - memmove(rom->ptr + size - bootblocksize, - rom->ptr + rom->size - bootblocksize, bootblocksize); - - /* Recacluate the location of the header */ - - offset = ROM_READL(rom, size - 12); - - rom->header = (struct cbfs_header *) - ROM_PTR(rom, size - (0xFFFFFFFF - offset) - 1); - - /* Put the new values in the header */ - rom->header->romsize = htonl(size); - rom->header->align = htonl(align); - - /* Truncate the file if we have to */ - - if (size < rom->size) { - munmap(rom->ptr, rom->size); - - rom->ptr = NULL; - - if (ftruncate(rom->fd, size)) { - ERROR("Unable to truncate the ROM\n"); - return -1; - } - - rom->ptr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, - rom->fd, 0); - - if (rom->ptr == MAP_FAILED) { - ERROR("Unable to truncate the ROM\n"); - return -1; - } - } - - rom->size = size; - rom->fssize = size - bootblocksize; - - return 0; -} diff --git a/util/cbfstool/tools/Makefile b/util/cbfstool/tools/Makefile deleted file mode 100644 index e750c21bd7..0000000000 --- a/util/cbfstool/tools/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -tobj ?= $(shell pwd) -tsrc ?= $(shell pwd) - -CFLAGS=-g -Wall - -TARGETS += $(tobj)/cbfs-mkstage $(tobj)/cbfs-mkpayload - -tools: $(tobj)/cbfs-mkstage $(tobj)/cbfs-mkpayload - -include $(tsrc)/lzma/Makefile - -COMMON = common.o compress.o $(LZMA_OBJ) - -$(tobj)/cbfs-mkstage: $(tobj)/cbfs-mkstage.o $(patsubst %,$(tobj)/%,$(COMMON)) - $(HOSTCXX) $(CFLAGS) -o $@ $^ - -$(tobj)/cbfs-mkpayload: $(tobj)/cbfs-mkpayload.o $(patsubst %,$(tobj)/%,$(COMMON)) - $(HOSTCXX) $(CFLAGS) -o $@ $^ - -$(tobj)/%.o: %.c - $(HOSTCC) $(CFLAGS) -c -o $@ $< - -tools-clean: - rm -f $(tobj)/cbfs-mkpayload.o $(tobj)/cbfs-mkstage.o $(patsubst %,$(tobj)/%,$(COMMON)) - rm -f $(tobj)/cbfs-mkpayload $(tobj)/cbfs-mkstage - diff --git a/util/cbfstool/tools/Makefile.inc b/util/cbfstool/tools/Makefile.inc deleted file mode 100644 index 0ef79ea438..0000000000 --- a/util/cbfstool/tools/Makefile.inc +++ /dev/null @@ -1,23 +0,0 @@ - -tobj ?= $(obj)/util/cbfstool/tools -tsrc ?= $(top)/util/cbfstool/tools - -include $(tsrc)/lzma/Makefile.inc - -COMMON = common.o compress.o $(LZMA_OBJ) - -ifdef POST_EVALUATION - -$(tobj)/cbfs-mkstage: $(tobj)/cbfs-mkstage.o $(patsubst %,$(tobj)/%,$(COMMON)) - printf " HOSTCXX $(subst $(obj)/,,$(@)) (link)\n" - $(HOSTCXX) $(HOSTCXXFLAGS) -o $@ $^ - -$(tobj)/cbfs-mkpayload: $(tobj)/cbfs-mkpayload.o $(patsubst %,$(tobj)/%,$(COMMON)) - printf " HOSTCXX $(subst $(obj)/,,$(@)) (link)\n" - $(HOSTCXX) $(HOSTCFLAGS) -o $@ $^ - -$(tobj)/%.o: $(tsrc)/%.c - printf " HOSTCC $(subst $(obj)/,,$(@))\n" - $(HOSTCC) $(HOSTCFLAGS) -c -o $@ $< - -endif diff --git a/util/cbfstool/tools/common.c b/util/cbfstool/tools/common.c deleted file mode 100644 index 377561bc52..0000000000 --- a/util/cbfstool/tools/common.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * cbfstool - * - * Copyright (C) 2008 Jordan Crouse - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -#include -#include "elf.h" -#include -#include -#include -#include -#include - -#include "common.h" - -#define BLOCKSIZE (1024 * 16) - -void file_write_from_buffer(int fd, unsigned char *buffer, int size) -{ - unsigned char *ptr = buffer; - - while (size) { - int ret = write(fd, ptr, size); - - if (ret == -1) - break; - - size -= ret; - ptr += ret; - } -} - -unsigned char *file_read_to_buffer(int fd, int *fsize) -{ - unsigned char *buffer = malloc(BLOCKSIZE); - unsigned char *ptr = buffer; - - int bsize = BLOCKSIZE; - int remain = BLOCKSIZE; - int size = 0; - int ret; - - if (buffer == NULL) - return NULL; - - while (1) { - ret = read(fd, ptr, remain); - - if (ret <= 0) - break; - - remain -= ret; - ptr += ret; - size += ret; - - /* Allocate more memory */ - - if (remain == 0) { - buffer = realloc(buffer, bsize + BLOCKSIZE); - - if (buffer == NULL) - return NULL; - - ptr = buffer + size; - - bsize += BLOCKSIZE; - remain = BLOCKSIZE; - } - } - - if (ret == 0) { - *fsize = size; - return buffer; - } - - *fsize = 0; - free(buffer); - return NULL; -} - -unsigned char *file_read(const char *filename, int *fsize) -{ - int fd = open(filename, O_RDONLY); - unsigned char *buffer; - - if (fd == -1) - return NULL; - - buffer = file_read_to_buffer(fd, fsize); - close(fd); - return buffer; -} - -void file_write(const char *filename, unsigned char *buffer, int size) -{ - int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, - S_IRUSR | S_IWUSR); - - if (fd == -1) { - fprintf(stderr, "E: Could not create %s: %m\n", filename); - return; - } - - file_write_from_buffer(fd, buffer, size); - close(fd); -} - -int iself(unsigned char *input) -{ - Elf32_Ehdr *ehdr = (Elf32_Ehdr *) input; - return !memcmp(ehdr->e_ident, ELFMAG, 4); -} diff --git a/util/cbfstool/tools/common.h b/util/cbfstool/tools/common.h deleted file mode 100644 index 146c828f6a..0000000000 --- a/util/cbfstool/tools/common.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * cbfstool - * - * Copyright (C) 2008 Jordan Crouse - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -#ifndef _COMMON_H_ -#define _COMMON_H_ - -int iself(unsigned char *input); -unsigned char *file_read(const char *filename, int *fsize); -void file_write(const char *filename, unsigned char *buffer, int size); -unsigned char *file_read_to_buffer(int fd, int *fsize); -void file_write_from_buffer(int fd, unsigned char *buffer, int size); - -/* compress.c */ - -void lzma_compress(char *in, int in_len, char *out, int *out_len); -void none_compress(char *in, int in_len, char *out, int *out_len); - -#endif diff --git a/util/cbfstool/types.c b/util/cbfstool/types.c deleted file mode 100644 index 88b4ea70b9..0000000000 --- a/util/cbfstool/types.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * cbfstool - * - * Copyright (C) 2008 Jordan Crouse - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -#include -#include "cbfstool.h" - -static const struct { - char *type; - unsigned int value; - int (*detect) (const char *filename); - int (*handler) (const char *filename, const char *name); -} component_types[] = { - { -NULL, 0xFF, NULL, NULL},}; - -int parse_type(const char *str, unsigned int *type) -{ - int i; - for (i = 0; component_types[i].type != NULL; i++) { - if (!strncmp(str, component_types[i].type, - strlen(compoent_types[i].type))) { - *type = component_types[i].value; - return 0; - } - } - - return -1; -} - -int detect_type(const char *filename) -{ - - int i; - - for (i = 0; component_types[i].type != NULL; i++) { - if (component_types[i].detect && - !component_types[i].detect(filename)) - return component_types[i].value; - - } -} - -int handle_type(const char *filename, int type, int *ret) -{ - /* Now send the file to the required handler */ - for (i = 0; component_types[i].type != NULL; i++) { - if (type == component_types[i].value) { - *ret = component_types[i].handler(config, - argv[0], argv[1]); - return 0; - } - } - - return -1; -} - -void get_type(int type, char *buffer, int len) -{ - for (i = 0; component_types[i].type != NULL; i++) { - if (type == component_types[i].value) { - strncpy(buffer, component_types[i].type, len - 1); - buffer[len - 1] = '\0'; - return; - } - } - - snprintf(buffer, len, "%x\n", type); -} diff --git a/util/cbfstool/util.c b/util/cbfstool/util.c deleted file mode 100644 index aa7c2183fc..0000000000 --- a/util/cbfstool/util.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * cbfstool - * - * Copyright (C) 2008 Jordan Crouse - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include "cbfstool.h" - -int uninitialized_flash_value = 0xff; - -void flashinit(void *ptr, size_t len) -{ - memset(ptr, uninitialized_flash_value, len); -} - -int get_size(const char *size) -{ - char *next; - int val = strtoul(size, &next, 0); - - /* Support modifiers for the size kK and mM for kbytes and - mbytes respectfully */ - - if (next != NULL) { - if (*next == 'k' || *next == 'K') - val *= 1024; - else if (*next == 'm' || *next == 'M') - val *= (1024 * 1024); - } - - return val; -} - -int copy_from_fd(int fd, void *ptr, int size) -{ - unsigned char *p = ptr; - - while (size > 0) { - int ret = read(fd, p, size); - - if (ret == -1) { - ERROR("Error while reading: %m\n"); - return -1; - } - - if (ret == 0) { - ERROR("Unexpected end of file\n"); - return -1; - } - - p += ret; - size -= ret; - } - - return 0; -} - -int size_and_open(const char *filename, unsigned int *size) -{ - struct stat s; - - int fd = open(filename, O_RDONLY); - - if (fd == -1) { - ERROR("Unable to open %s: %m\n", filename); - return -1; - } - - if (fstat(fd, &s)) { - ERROR("Unable to stat %s: %m\n", filename); - close(fd); - return -1; - } - - *size = s.st_size; - return fd; -} - -int map_rom(struct rom *rom, int size) -{ - rom->ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, - rom->fd, 0); - - if (rom->ptr == MAP_FAILED) { - ERROR("Could not map the rom: %m\n"); - rom->ptr = NULL; - return -1; - } - - return 0; -} - -int open_rom(struct rom *rom, const char *filename) -{ - struct stat s; - unsigned long offset; - - if (stat(filename, &s)) { - ERROR("Could not stat %s: %m\n", filename); - return -1; - } - - rom->fd = open(filename, O_RDWR); - - if (rom->fd == -1) { - ERROR("Could not open %s: %m\n", filename); - rom->fd = 0; - return -1; - } - - if (map_rom(rom, s.st_size)) - goto err; - - /* Find the master header */ - - offset = ROM_READL(rom, s.st_size - 4); - - rom->header = (struct cbfs_header *) - ROM_PTR(rom, s.st_size - (0xFFFFFFFF - offset) - 1); - - if (ntohl(rom->header->magic) != HEADER_MAGIC) { - ERROR("This does not appear to be a valid ROM\n"); - goto err; - } - - /* Check that the alignment is correct */ - if (ntohl(rom->header->align) == 0) { - ERROR("The alignment in the ROM is 0 - probably malformed\n"); - goto err; - } - - /* Sanity check that the size matches the file size */ - - if (ntohl(rom->header->romsize) != s.st_size) { - ERROR("The ROM size in the header does not match the file\n"); - ERROR("ROM size is %d bytes, file size is %d bytes\n", - ntohl(rom->header->romsize), (unsigned int)s.st_size); - goto err; - } - - rom->size = ntohl(rom->header->romsize); - /* compute a 32-bit value of rombase. - * This does the right thing on 64-bit machines. - */ - rom->rombase = 0-rom->size; - rom->rombase &= 0xffffffff; - rom->fssize = rom->size - ntohl(rom->header->bootblocksize); - - return 0; - -err: - if (rom->ptr != NULL) - munmap(rom->ptr, s.st_size); - - if (rom->fd > 0) - close(rom->fd); - - rom->ptr = NULL; - rom->fd = 0; - return -1; -} - -int create_rom(struct rom *rom, const unsigned char *filename, - int romsize, const char *bootblockname, - int bootblocksize, int align) -{ - unsigned char null = '\0'; - - if (rom->fd != 0) { - ERROR("%s already exists - cannot create\n", filename); - return -1; - } - - /* Remember the size of the entire ROM */ - rom->size = romsize; - - /* The size of the archive section is everything but the bootblock and - * the cbfs master header. */ - rom->fssize = romsize - bootblocksize - sizeof(struct cbfs_header); - - /* Open the file descriptor */ - - rom->fd = open((char *)filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); - - if (rom->fd == -1) { - ERROR("Could not create %s: %m\n", filename); - return -1; - } - - /* Size the new file appropriately */ - lseek(rom->fd, romsize - 1, SEEK_SET); - write(rom->fd, &null, 1); - - if (map_rom(rom, romsize)) { - close(rom->fd); - return -1; - } - - /* mmap'ed pages are by default zero-filled. Fix that. */ - flashinit(rom->ptr, romsize); - - /* This is a pointer to the header for easy access */ - rom->header = (struct cbfs_header *) - ROM_PTR(rom, rom->size - bootblocksize - sizeof(struct cbfs_header)); - rom->header->magic = htonl(HEADER_MAGIC); - rom->header->romsize = htonl(romsize); - rom->header->bootblocksize = htonl(bootblocksize); - rom->header->align = htonl(align); - rom->header->offset = htonl(0); - - if (add_bootblock(rom, bootblockname) == -1) - return -1; - - /* Write the cbfs master header address at the end of the ROM. */ - - ROM_WRITEL(rom, rom->size - 4, - 0xFFFFFFFF - bootblocksize - sizeof(struct cbfs_header) + 1); - - /* write the empty header */ - rom_set_header(rom, (struct cbfs_file *)rom->ptr, "", -1, CBFS_COMPONENT_NULL); - return 0; -} - -int add_bootblock(struct rom *rom, const char *filename) -{ - unsigned int size; - int fd = size_and_open(filename, &size); - int ret; - - if (fd == -1) - return -1; - - if (size > ntohl(rom->header->bootblocksize)) { - ERROR("The bootblock size is not correct (%d vs %d)\n", - size, ntohl(rom->header->bootblocksize)); - return -1; - } - - /* Copy the bootblock into place at the end of the file */ - ret = copy_from_fd(fd, ROM_PTR(rom, rom->size - size), size); - - close(fd); - - if (ret) { - ERROR("Unable to add %s to the bootblock\n", filename); - return -1; - } - - return 0; -} - -int rom_exists(struct rom *rom) -{ - if (rom->fd <= 0) - return 0; - return 1; -} diff --git a/util/newconfig/config.g b/util/newconfig/config.g index b7f397d5c7..24983109e3 100644 --- a/util/newconfig/config.g +++ b/util/newconfig/config.g @@ -2257,7 +2257,7 @@ def writemakefile(path): file.write("\n") # cbfstool rules - file.write("\ncbfstool:\n\tmkdir -p cbfs/tools/lzma\n\t$(MAKE) -C $(TOP)/util/cbfstool obj=$(shell pwd)/cbfs\n") + file.write("\ncbfstool:\n\tmkdir -p cbfs\n\t$(MAKE) -C $(TOP)/util/cbfstool obj=$(shell pwd)/cbfs\n") file.write("\ncbfstool-clean:\n\t$(MAKE) -C $(TOP)/util/cbfstool obj=$(shell pwd)/cbfs clean\n\n") file.write("include Makefile.settings\n\n")