CBFS stuff:
- update, add, and improve comments - whitespace here and there - remove unused or write-only variables - improve debug output - only build payload.{nrv2b,lzma} for non-cbfs - improved error checking in cbfstool Signed-off-by: Stefan Reinauer <stepan@coresystems.de> Acked-by: Peter Stuge <peter@stuge.se> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4466 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
parent
aeb6c9870f
commit
f64893a94f
|
@ -5,6 +5,7 @@ uses CONFIG_USE_INIT
|
||||||
uses CONFIG_HAVE_FAILOVER_BOOT
|
uses CONFIG_HAVE_FAILOVER_BOOT
|
||||||
uses CONFIG_USE_FAILOVER_IMAGE
|
uses CONFIG_USE_FAILOVER_IMAGE
|
||||||
uses CONFIG_USE_FALLBACK_IMAGE
|
uses CONFIG_USE_FALLBACK_IMAGE
|
||||||
|
uses CONFIG_CBFS
|
||||||
|
|
||||||
init init/crt0.S.lb
|
init init/crt0.S.lb
|
||||||
|
|
||||||
|
@ -82,9 +83,12 @@ end
|
||||||
# catch the case where there is no compression
|
# catch the case where there is no compression
|
||||||
makedefine PAYLOAD-1:=payload
|
makedefine PAYLOAD-1:=payload
|
||||||
|
|
||||||
|
if CONFIG_CBFS
|
||||||
|
else
|
||||||
# match the case where a compression type is specified.
|
# match the case where a compression type is specified.
|
||||||
makedefine PAYLOAD-$(CONFIG_COMPRESSED_PAYLOAD_NRV2B):=payload.nrv2b
|
makedefine PAYLOAD-$(CONFIG_COMPRESSED_PAYLOAD_NRV2B):=payload.nrv2b
|
||||||
makedefine PAYLOAD-$(CONFIG_COMPRESSED_PAYLOAD_LZMA):=payload.lzma
|
makedefine PAYLOAD-$(CONFIG_COMPRESSED_PAYLOAD_LZMA):=payload.lzma
|
||||||
|
end
|
||||||
|
|
||||||
# catch the case where there is precompression. Yes, this bites.
|
# catch the case where there is precompression. Yes, this bites.
|
||||||
if CONFIG_PRECOMPRESSED_PAYLOAD
|
if CONFIG_PRECOMPRESSED_PAYLOAD
|
||||||
|
|
|
@ -142,7 +142,7 @@ str_copying_to_ram: .string "Uncompressing coreboot to RAM.\r\n"
|
||||||
#else
|
#else
|
||||||
str_copying_to_ram: .string "Copying coreboot to RAM.\r\n"
|
str_copying_to_ram: .string "Copying coreboot to RAM.\r\n"
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_CBFS
|
#if CONFIG_CBFS == 1
|
||||||
# if CONFIG_USE_FALLBACK_IMAGE == 1
|
# if CONFIG_USE_FALLBACK_IMAGE == 1
|
||||||
str_coreboot_ram_name: .string "fallback/coreboot_ram"
|
str_coreboot_ram_name: .string "fallback/coreboot_ram"
|
||||||
# else
|
# else
|
||||||
|
|
|
@ -107,11 +107,11 @@ int verify_ip_checksum(
|
||||||
* a machine, and implementing general relocation is hard.
|
* a machine, and implementing general relocation is hard.
|
||||||
*
|
*
|
||||||
* The solution:
|
* The solution:
|
||||||
* - Allocate a buffer twice the size of the coreboot image.
|
* - Allocate a buffer the size of the coreboot image plus additional
|
||||||
* - Anything that would overwrite coreboot copy into the lower half of
|
* required space.
|
||||||
|
* - Anything that would overwrite coreboot copy into the lower part of
|
||||||
* the buffer.
|
* the buffer.
|
||||||
* - After loading an ELF image copy coreboot to the upper half of the
|
* - After loading an ELF image copy coreboot to the top of the buffer.
|
||||||
* buffer.
|
|
||||||
* - Then jump to the loaded image.
|
* - Then jump to the loaded image.
|
||||||
*
|
*
|
||||||
* Benefits:
|
* Benefits:
|
||||||
|
|
|
@ -74,15 +74,13 @@ struct ip_checksum_vcb {
|
||||||
void * cbfs_load_payload(struct lb_memory *lb_mem, const char *name)
|
void * cbfs_load_payload(struct lb_memory *lb_mem, const char *name)
|
||||||
{
|
{
|
||||||
int selfboot(struct lb_memory *mem, struct cbfs_payload *payload);
|
int selfboot(struct lb_memory *mem, struct cbfs_payload *payload);
|
||||||
struct cbfs_payload *payload = (struct cbfs_payload *)
|
struct cbfs_payload *payload;
|
||||||
cbfs_find_file(name, CBFS_TYPE_PAYLOAD);
|
|
||||||
|
|
||||||
struct cbfs_payload_segment *segment, *first_segment;
|
|
||||||
|
|
||||||
|
payload = (struct cbfs_payload *)cbfs_find_file(name, CBFS_TYPE_PAYLOAD);
|
||||||
if (payload == NULL)
|
if (payload == NULL)
|
||||||
return (void *) -1;
|
return (void *) -1;
|
||||||
printk_debug("Got a payload\n");
|
printk_debug("Got a payload\n");
|
||||||
first_segment = segment = &payload->segments;
|
|
||||||
selfboot(lb_mem, payload);
|
selfboot(lb_mem, payload);
|
||||||
printk_emerg("SELFBOOT RETURNED!\n");
|
printk_emerg("SELFBOOT RETURNED!\n");
|
||||||
|
|
||||||
|
@ -95,11 +93,11 @@ void * cbfs_load_payload(struct lb_memory *lb_mem, const char *name)
|
||||||
* a machine, and implementing general relocation is hard.
|
* a machine, and implementing general relocation is hard.
|
||||||
*
|
*
|
||||||
* The solution:
|
* The solution:
|
||||||
* - Allocate a buffer twice the size of the coreboot image.
|
* - Allocate a buffer the size of the coreboot image plus additional
|
||||||
* - Anything that would overwrite coreboot copy into the lower half of
|
* required space.
|
||||||
|
* - Anything that would overwrite coreboot copy into the lower part of
|
||||||
* the buffer.
|
* the buffer.
|
||||||
* - After loading an ELF image copy coreboot to the upper half of the
|
* - After loading an ELF image copy coreboot to the top of the buffer.
|
||||||
* buffer.
|
|
||||||
* - Then jump to the loaded image.
|
* - Then jump to the loaded image.
|
||||||
*
|
*
|
||||||
* Benefits:
|
* Benefits:
|
||||||
|
@ -270,9 +268,9 @@ static void relocate_segment(unsigned long buffer, struct segment *seg)
|
||||||
new->s_dstaddr,
|
new->s_dstaddr,
|
||||||
new->s_dstaddr + new->s_filesz,
|
new->s_dstaddr + new->s_filesz,
|
||||||
new->s_dstaddr + new->s_memsz);
|
new->s_dstaddr + new->s_memsz);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Slice off a piece at the end
|
/* Slice off a piece at the end
|
||||||
* that doesn't conflict with coreboot
|
* that doesn't conflict with coreboot
|
||||||
*/
|
*/
|
||||||
if (end > lb_end) {
|
if (end > lb_end) {
|
||||||
|
@ -301,16 +299,13 @@ static void relocate_segment(unsigned long buffer, struct segment *seg)
|
||||||
seg->phdr_next->phdr_prev = new;
|
seg->phdr_next->phdr_prev = new;
|
||||||
seg->phdr_next = new;
|
seg->phdr_next = new;
|
||||||
|
|
||||||
/* compute the new value of end */
|
|
||||||
end = start + len;
|
|
||||||
|
|
||||||
printk_spew(" late: [0x%016lx, 0x%016lx, 0x%016lx)\n",
|
printk_spew(" late: [0x%016lx, 0x%016lx, 0x%016lx)\n",
|
||||||
new->s_dstaddr,
|
new->s_dstaddr,
|
||||||
new->s_dstaddr + new->s_filesz,
|
new->s_dstaddr + new->s_filesz,
|
||||||
new->s_dstaddr + new->s_memsz);
|
new->s_dstaddr + new->s_memsz);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now retarget this segment onto the bounce buffer */
|
/* Now retarget this segment onto the bounce buffer */
|
||||||
/* sort of explanation: the buffer is a 1:1 mapping to coreboot.
|
/* sort of explanation: the buffer is a 1:1 mapping to coreboot.
|
||||||
* so you will make the dstaddr be this buffer, and it will get copied
|
* so you will make the dstaddr be this buffer, and it will get copied
|
||||||
|
@ -332,7 +327,6 @@ static int build_self_segment_list(
|
||||||
{
|
{
|
||||||
struct segment *new;
|
struct segment *new;
|
||||||
struct segment *ptr;
|
struct segment *ptr;
|
||||||
int datasize;
|
|
||||||
struct cbfs_payload_segment *segment, *first_segment;
|
struct cbfs_payload_segment *segment, *first_segment;
|
||||||
memset(head, 0, sizeof(*head));
|
memset(head, 0, sizeof(*head));
|
||||||
head->phdr_next = head->phdr_prev = head;
|
head->phdr_next = head->phdr_prev = head;
|
||||||
|
@ -340,66 +334,82 @@ static int build_self_segment_list(
|
||||||
first_segment = segment = &payload->segments;
|
first_segment = segment = &payload->segments;
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
printk_debug("Segment %p\n", segment);
|
printk_debug("Loading segment from rom address 0x%p\n", segment);
|
||||||
switch(segment->type) {
|
switch(segment->type) {
|
||||||
default: printk_emerg("Bad segment type %x\n", segment->type);
|
|
||||||
return -1;
|
|
||||||
case PAYLOAD_SEGMENT_PARAMS:
|
case PAYLOAD_SEGMENT_PARAMS:
|
||||||
printk_info("found param section\n");
|
printk_debug(" parameter section (skipped)\n");
|
||||||
segment++;
|
segment++;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case PAYLOAD_SEGMENT_CODE:
|
case PAYLOAD_SEGMENT_CODE:
|
||||||
case PAYLOAD_SEGMENT_DATA:
|
case PAYLOAD_SEGMENT_DATA:
|
||||||
printk_info( "%s: ", segment->type == PAYLOAD_SEGMENT_CODE ?
|
printk_debug(" %s (compression=%x)\n",
|
||||||
"code" : "data");
|
segment->type == PAYLOAD_SEGMENT_CODE ? "code" : "data",
|
||||||
new = malloc(sizeof(*new));
|
ntohl(segment->compression));
|
||||||
new->s_dstaddr = ntohl((u32) segment->load_addr);
|
new = malloc(sizeof(*new));
|
||||||
new->s_memsz = ntohl(segment->mem_len);
|
new->s_dstaddr = ntohl((u32) segment->load_addr);
|
||||||
new->compression = ntohl(segment->compression);
|
new->s_memsz = ntohl(segment->mem_len);
|
||||||
|
new->compression = ntohl(segment->compression);
|
||||||
|
|
||||||
|
new->s_srcaddr = (u32) ((unsigned char *) first_segment) + ntohl(segment->offset);
|
||||||
|
new->s_filesz = ntohl(segment->len);
|
||||||
|
printk_debug(" New segment dstaddr 0x%lx memsize 0x%lx srcaddr 0x%lx filesize 0x%lx\n",
|
||||||
|
new->s_dstaddr, new->s_memsz, new->s_srcaddr, new->s_filesz);
|
||||||
|
/* Clean up the values */
|
||||||
|
if (new->s_filesz > new->s_memsz) {
|
||||||
|
new->s_filesz = new->s_memsz;
|
||||||
|
}
|
||||||
|
printk_debug(" (cleaned up) New segment addr 0x%lx size 0x%lx offset 0x%lx filesize 0x%lx\n",
|
||||||
|
new->s_dstaddr, new->s_memsz, new->s_srcaddr, new->s_filesz);
|
||||||
|
break;
|
||||||
|
|
||||||
datasize = ntohl(segment->len);
|
|
||||||
new->s_srcaddr = (u32) ((unsigned char *) first_segment) + ntohl(segment->offset);
|
|
||||||
new->s_filesz = ntohl(segment->len);
|
|
||||||
printk_debug("New segment dstaddr 0x%lx memsize 0x%lx srcaddr 0x%lx filesize 0x%lx\n",
|
|
||||||
new->s_dstaddr, new->s_memsz, new->s_srcaddr, new->s_filesz);
|
|
||||||
/* Clean up the values */
|
|
||||||
if (new->s_filesz > new->s_memsz) {
|
|
||||||
new->s_filesz = new->s_memsz;
|
|
||||||
}
|
|
||||||
printk_debug("(cleaned up) New segment addr 0x%lx size 0x%lx offset 0x%lx filesize 0x%lx\n",
|
|
||||||
new->s_dstaddr, new->s_memsz, new->s_srcaddr, new->s_filesz);
|
|
||||||
break;
|
|
||||||
case PAYLOAD_SEGMENT_BSS:
|
case PAYLOAD_SEGMENT_BSS:
|
||||||
printk_info("BSS %p/%d\n", (void *) ntohl((u32) segment->load_addr),
|
printk_debug(" BSS 0x%p (%d byte)\n", (void *) ntohl((u32) segment->load_addr),
|
||||||
ntohl(segment->mem_len));
|
ntohl(segment->mem_len));
|
||||||
new = malloc(sizeof(*new));
|
new = malloc(sizeof(*new));
|
||||||
new->s_filesz = 0;
|
new->s_filesz = 0;
|
||||||
new->s_dstaddr = ntohl((u32) segment->load_addr);
|
new->s_dstaddr = ntohl((u32) segment->load_addr);
|
||||||
new->s_memsz = ntohl(segment->mem_len);
|
new->s_memsz = ntohl(segment->mem_len);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PAYLOAD_SEGMENT_ENTRY:
|
case PAYLOAD_SEGMENT_ENTRY:
|
||||||
printk_info("Entry %p\n", (void *) ntohl((u32) segment->load_addr));
|
printk_debug(" Entry Point 0x%p\n", (void *) ntohl((u32) segment->load_addr));
|
||||||
*entry = ntohl((u32) segment->load_addr);
|
*entry = ntohl((u32) segment->load_addr);
|
||||||
|
/* Per definition, a payload always has the entry point
|
||||||
|
* as last segment. Thus, we use the occurence of the
|
||||||
|
* entry point as break condition for the loop.
|
||||||
|
* Can we actually just look at the number of section?
|
||||||
|
*/
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* We found something that we don't know about. Throw
|
||||||
|
* hands into the sky and run away!
|
||||||
|
*/
|
||||||
|
printk_emerg("Bad segment type %x\n", segment->type);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
segment++;
|
segment++;
|
||||||
|
|
||||||
for(ptr = head->next; ptr != head; ptr = ptr->next) {
|
for(ptr = head->next; ptr != head; ptr = ptr->next) {
|
||||||
if (new->s_srcaddr < ntohl((u32) segment->load_addr))
|
if (new->s_srcaddr < ntohl((u32) segment->load_addr))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Order by stream offset */
|
/* Order by stream offset */
|
||||||
new->next = ptr;
|
new->next = ptr;
|
||||||
new->prev = ptr->prev;
|
new->prev = ptr->prev;
|
||||||
ptr->prev->next = new;
|
ptr->prev->next = new;
|
||||||
ptr->prev = new;
|
ptr->prev = new;
|
||||||
|
|
||||||
/* Order by original program header order */
|
/* Order by original program header order */
|
||||||
new->phdr_next = head;
|
new->phdr_next = head;
|
||||||
new->phdr_prev = head->phdr_prev;
|
new->phdr_prev = head->phdr_prev;
|
||||||
head->phdr_prev->phdr_next = new;
|
head->phdr_prev->phdr_next = new;
|
||||||
head->phdr_prev = new;
|
head->phdr_prev = new;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,10 +418,8 @@ static int load_self_segments(
|
||||||
struct lb_memory *mem,
|
struct lb_memory *mem,
|
||||||
struct cbfs_payload *payload)
|
struct cbfs_payload *payload)
|
||||||
{
|
{
|
||||||
unsigned long offset;
|
|
||||||
struct segment *ptr;
|
struct segment *ptr;
|
||||||
|
|
||||||
offset = 0;
|
|
||||||
unsigned long required_bounce_size = lb_end - lb_start;
|
unsigned long required_bounce_size = lb_end - lb_start;
|
||||||
for(ptr = head->next; ptr != head; ptr = ptr->next) {
|
for(ptr = head->next; ptr != head; ptr = ptr->next) {
|
||||||
if (!overlaps_coreboot(ptr)) continue;
|
if (!overlaps_coreboot(ptr)) continue;
|
||||||
|
@ -429,7 +437,7 @@ static int load_self_segments(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
for(ptr = head->next; ptr != head; ptr = ptr->next) {
|
for(ptr = head->next; ptr != head; ptr = ptr->next) {
|
||||||
unsigned char *dest,*src;
|
unsigned char *dest, *src;
|
||||||
printk_debug("Loading Segment: addr: 0x%016lx memsz: 0x%016lx filesz: 0x%016lx\n",
|
printk_debug("Loading Segment: addr: 0x%016lx memsz: 0x%016lx filesz: 0x%016lx\n",
|
||||||
ptr->s_dstaddr, ptr->s_memsz, ptr->s_filesz);
|
ptr->s_dstaddr, ptr->s_memsz, ptr->s_filesz);
|
||||||
|
|
||||||
|
|
|
@ -59,16 +59,16 @@ struct cbfs_header *cbfs_master_header(void)
|
||||||
struct cbfs_header *header;
|
struct cbfs_header *header;
|
||||||
|
|
||||||
void *ptr = (void *)*((unsigned long *) CBFS_HEADPTR_ADDR);
|
void *ptr = (void *)*((unsigned long *) CBFS_HEADPTR_ADDR);
|
||||||
printk_debug("Check CBFS header at %p\n", ptr);
|
printk_spew("Check CBFS header at %p\n", ptr);
|
||||||
header = (struct cbfs_header *) ptr;
|
header = (struct cbfs_header *) ptr;
|
||||||
|
|
||||||
printk_debug("magic is %08x\n", ntohl(header->magic));
|
printk_spew("magic is %08x\n", ntohl(header->magic));
|
||||||
if (ntohl(header->magic) != CBFS_HEADER_MAGIC) {
|
if (ntohl(header->magic) != CBFS_HEADER_MAGIC) {
|
||||||
printk_err("NO CBFS HEADER\n");
|
printk_err("ERROR: No valid CBFS header found!\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
printk_debug("Found CBFS header at %p\n", ptr);
|
printk_spew("Found CBFS header at %p\n", ptr);
|
||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ struct cbfs_file *cbfs_find(const char *name)
|
||||||
while(1) {
|
while(1) {
|
||||||
struct cbfs_file *file = (struct cbfs_file *) offset;
|
struct cbfs_file *file = (struct cbfs_file *) offset;
|
||||||
if (!cbfs_check_magic(file)) return NULL;
|
if (!cbfs_check_magic(file)) return NULL;
|
||||||
printk_info("Check %s\n", CBFS_NAME(file));
|
printk_debug("Check %s\n", CBFS_NAME(file));
|
||||||
if (!strcmp(CBFS_NAME(file), name))
|
if (!strcmp(CBFS_NAME(file), name))
|
||||||
return file;
|
return file;
|
||||||
|
|
||||||
|
|
|
@ -312,6 +312,29 @@ struct cbfs_file *rom_find_next(struct rom *rom, struct cbfs_file *prev)
|
||||||
ntohl(rom->header->align)));
|
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 *rom_find_by_name(struct rom *rom, const char *name)
|
||||||
{
|
{
|
||||||
struct cbfs_file *c = rom_find_first(rom);
|
struct cbfs_file *c = rom_find_first(rom);
|
||||||
|
@ -363,6 +386,24 @@ int rom_remove(struct rom *rom, const char *name)
|
||||||
|
|
||||||
c->type = CBFS_COMPONENT_DELETED;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,6 +435,7 @@ int rom_extract(struct rom *rom, const char *name, void** buf, int *size )
|
||||||
int rom_add(struct rom *rom, const char *name, void *buffer, unsigned long address, int size, int type)
|
int rom_add(struct rom *rom, const char *name, void *buffer, unsigned long address, int size, int type)
|
||||||
{
|
{
|
||||||
struct cbfs_file *c;
|
struct cbfs_file *c;
|
||||||
|
int csize;
|
||||||
|
|
||||||
if (rom_find_by_name(rom, name)) {
|
if (rom_find_by_name(rom, name)) {
|
||||||
ERROR("Component %s already exists in this rom\n", name);
|
ERROR("Component %s already exists in this rom\n", name);
|
||||||
|
@ -410,7 +452,28 @@ int rom_add(struct rom *rom, const char *name, void *buffer, unsigned long addre
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(((unsigned char *)c) + ntohl(c->offset), buffer, size);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue