Stefan Reinauer has uploaded this change for review. ( https://review.coreboot.org/c/em100/+/36943 )
Change subject: WIP: Use binaries from Windows installer directly ......................................................................
WIP: Use binaries from Windows installer directly
Right now we are parsing the config files into em100pro_chips.h and expect the users to deal with firmware by themselves. With a simple tar implementation we could bundle the original files with the binary much easier.
DO NOT COMMIT
Change-Id: I8c360e96ce42fd78141a1564976454711e20f527 Signed-off-by: Stefan Reinauer stefan.reinauer@coreboot.org --- A configs.tar A firmware.tar A tar.c 3 files changed, 217 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/em100 refs/changes/43/36943/1
diff --git a/configs.tar b/configs.tar new file mode 100644 index 0000000..3d71d71 --- /dev/null +++ b/configs.tar Binary files differ diff --git a/firmware.tar b/firmware.tar new file mode 100644 index 0000000..10ed9d9 --- /dev/null +++ b/firmware.tar Binary files differ diff --git a/tar.c b/tar.c new file mode 100644 index 0000000..6f4a117 --- /dev/null +++ b/tar.c @@ -0,0 +1,217 @@ +#define _GNU_SOURCE +//#define DEBUG +#include <stddef.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +/* Debugging */ +#include <stdint.h> +#include <ctype.h> +static void hexdump(const void *memory, size_t length) +{ + int i; + uint8_t *m; + int all_zero = 0; + int all_one = 0; + + m = (uint8_t *) memory; + + for (i = 0; i < length; i += 16) { + int j; + + all_zero++; + all_one++; + for (j = 0; j < 16; j++) { + if (m[i + j] != 0) { + all_zero = 0; + break; + } + } + for (j = 0; j < 16; j++) { + if (m[i + j] != 0xff) { + all_one = 0; + break; + } + } + if (all_zero < 2 && all_one < 2) { + printf( "%08x:", i); + for (j = 0; j < 16; j++) + printf( " %02x", m[i + j]); + printf(" "); + for (j = 0; j < 16; j++) + printf( "%c", + isprint(m[i + j]) ? m[i + j] : '.'); + printf( "\n"); + } else if (all_zero == 2 || all_one == 2) { + printf( "...\n"); + } + } +} +/* Debugging */ + +#define ROUND_UP(n, inc) (n + (inc - n % inc) % inc) + +typedef struct { + char name[100]; + char mode[8]; + char owner[8]; + char group[8]; + char size[12]; + char mtime[12]; + char checksum[8]; + char type; + char linkname[100]; + char magic[6]; + char version[2]; + char uname[32]; + char gname[32]; + char devmajor[8]; + char devminor[8]; + char prefix[155]; + char padding[12]; +} __attribute__((packed)) tar_raw_header_t; + +static unsigned int checksum(tar_raw_header_t *file) +{ + int i, chk_off = offsetof(tar_raw_header_t, checksum); + char *raw = (char *)file; + unsigned int chksum = 256; + + for (i = 0; i < sizeof(tar_raw_header_t); i++) { + if (i >= chk_off && i < chk_off + 8) + continue; + chksum += raw[i]; + } + return chksum; +} + +int tar_ls(char *tar, size_t tar_length) +{ + size_t i = 0; + + while (i < tar_length) { + tar_raw_header_t *f = (tar_raw_header_t *)(tar + i); + if (f->name[0] == 0) /* null header at end of tar */ + break; + + unsigned int size = strtol(f->size, NULL, 8); + unsigned int cksum = strtol(f->checksum, NULL, 8); + unsigned int ok = (checksum(f) == cksum); + + if(!ok) + break; + + printf("name: "%s" (%s)\n", f->name, ok?"OK":"FAIL"); +#ifdef DEBUG + printf(" mode: "%s"\n", f->mode); + printf(" owner: "%s"\n", f->owner); + printf(" group: "%s"\n", f->group); + printf(" size: %011o\n", size); + printf(" mtime: "%s"\n", f->mtime); + printf(" checksum: %07o\n", cksum); + char *t; + switch (f->type) { + case '0': t = "regular"; break; + case '1': t = "link"; break; + case '2': t = "reserved"; break; + case '3': t = "character special"; break; + case '4': t = "block special"; break; + case '5': t = "directory"; break; + case '6': t = "fifo special" break; + case '7': t = "contiguous"; break; + default: t = "<unknown>"; break; + } + printf(" type: %s\n", t); + printf(" linkname: "%s"\n\n", strndupa(f->linkname, 100)); +#endif + + i += sizeof(tar_raw_header_t) + ROUND_UP(size, 512); + } + + return 0; +} + +int tar_find(char *tar, size_t tar_length, char *name, char **result, size_t *result_length) +{ + size_t i = 0; + + while (i < tar_length) { + tar_raw_header_t *f = (tar_raw_header_t *)(tar + i); + if (f->name[0] == 0) /* null header at end of tar */ + break; + + unsigned int size = strtol(f->size, NULL, 8); + unsigned int cksum = strtol(f->checksum, NULL, 8); + unsigned int ok = (checksum(f) == cksum); + + if(!ok) + break; + + if (!strncmp(name, f->name, 100) && f->type == '0') { + *result = tar + i + sizeof(tar_raw_header_t); + *result_length = size; + return 0; + } + i += sizeof(tar_raw_header_t) + ROUND_UP(size, 512); + } + + return 1; +} + +int main(int argc, char *argv[]) +{ + FILE *f; + size_t fsize; + char *fw; + + char *filename = "firmware.tar"; + + f = fopen(filename, "rb"); + if (!f) { + perror(filename); + return 0; + } + + fseek(f, 0, SEEK_END); + fsize = ftell(f); + if (fsize < 0) { + perror(filename); + fclose(f); + return 0; + } + fseek(f, 0, SEEK_SET); + + fw = malloc(fsize); + if (!fw) { + printf("ERROR: out of memory.\n"); + fclose(f); + return 0; + } + if (fread(fw, fsize, 1, f) != 1) { + perror(filename); + fclose(f); + free(fw); + return 0; + } + fclose(f); + + tar_ls(fw, fsize); + + char *img; + size_t img_length; + int ret; + + ret = tar_find(fw, fsize, "firmware/em100pro_fw_2.27_0.89_3.3V.dpfw", + &img, &img_length); + + if (ret) { + printf("FILE NOT FOUND\n"); + } else { + printf("firmware/em100pro_fw_2.27_0.89_3.3V.dpfw:\n\n"); + hexdump(img, img_length); + } + + free(fw); +} +