Hi list, Since the way we use to add stage to a rom file is highly depended on the 1-1 address map on X86 so we can not use it to add stage to a rom file on ARM. I create a new way using a binary file to add stage to a rom file. We can use it as following: cbfstool romfile add-stage a-bin-file NAME COMP entry-address o/a the last parameter we use is for telling cbfstool whether this file a romstage(o) or a ramstage(a). Since we use a binary file that this file could not tell cbfstool the entry address, we need to pass the entry address to cbfstool.
Is this a good way to do this? Or there are any other ways better to do it? Any comments are very very welcome!
P.S. Could I work on porting coreboot to Armltd versatilepb (which can be emulated by QEMU) instead of Marvell's SOC? Because first It is so difficult for me to get the necessary information of Marvell's SOC, second, You all can test my porting easily.
Following is what I changed to the cbfstool:
diff --git a/util/cbfstool/cbfs-mkstage.c b/util/cbfstool/cbfs-mkstage.c index e90bc93..b42815f 100644 --- a/util/cbfstool/cbfs-mkstage.c +++ b/util/cbfstool/cbfs-mkstage.c @@ -193,3 +193,62 @@ int parse_elf_to_stage(unsigned char *input, unsigned char **output, *location -= sizeof(struct cbfs_stage); return sizeof(struct cbfs_stage) + stage->len; } + +/* returns size of result, or -1 if error */ +int parse_bin_to_stage(unsigned char *input, unsigned int size, + unsigned char **output, comp_algo algo, + uint32_t *location, char kind) +{ + unsigned char *out; + struct cbfs_stage *stage; + + comp_func_ptr compress = compression_function(algo); + if (!compress) + return -1; + + /* Now make the output buffer */ + out = calloc(sizeof(struct cbfs_stage) + size, 1); + + if (out == NULL) { + fprintf(stderr, "E: Unable to allocate memory: %m\n"); + return -1; + } + + stage = (struct cbfs_stage *)out; + + stage->memlen = size; + stage->compression = algo; + + compress(input, size, + (char *)(out + sizeof(struct cbfs_stage)), (int *)&stage->len); + + *output = out; + + /* + * On ARM, every instruction should be aligned to 0x4, + * so we need to test the entry address provided by + * cbfstool or user. + */ + uint32_t address; + if (kind == 'o') { + address = *location + rombase; + if((address & 0x3) != 0) { + printf("Error: entry address is not aligned to 0x4."); + return -1; + } + stage->load = stage->entry = address; + *location -= sizeof(struct cbfs_stage); + } else if (kind == 'a') { + address = *location; + if((address & 0x3) != 0) { + printf("Error: entry address is not aligned to 0x4."); + return -1; + } + stage->load = stage->entry = address; + *location = 0; + } else { + return -1; + } + + return sizeof(struct cbfs_stage) + stage->len; +} diff --git a/util/cbfstool/cbfstool.c b/util/cbfstool/cbfstool.c index 811310b..ad0fdab 100644 --- a/util/cbfstool/cbfstool.c +++ b/util/cbfstool/cbfstool.c @@ -177,7 +177,22 @@ static int cbfs_add_stage(int argc, char **argv) base = strtoul(argv[6], NULL, 0); } unsigned char *stage; - filesize = parse_elf_to_stage(filedata, &stage, algo, &base); + switch(arch) { + case ARCH_ARM: + if (argc != 8) { + printf("not enough arguments to '%s'.\n", cmd); + return 1; + } + char kind = argv[7][0]; + filesize = parse_bin_to_stage(filedata, filesize, &stage, algo, &base, kind); + break; + case ARCH_X86: + filesize = parse_elf_to_stage(filedata, &stage, algo, &base); + break; + default: + printf("Unknown architecture\n"); + exit(1); + } cbfsfile = create_cbfs_file(cbfsname, stage, &filesize, CBFS_COMPONENT_STAGE, &base); @@ -302,7 +317,7 @@ void usage(void) "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" + " add-stage FILE NAME [COMP] [base] [kind] Add a stage to the ROM\n" " create ARCH SIZE BOOTBLOCK [ALIGN] Create a ROM file\n" " locate FILE NAME ALIGN Find a place for a file of that size\n" " print Show the contents of the ROM\n"