mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
3.5 KiB
151 lines
3.5 KiB
// SPDX-License-Identifier: GPL-2.0 |
|
/* |
|
* Makes a tree bootable image for IBM Evaluation boards. |
|
* Basically, just take a zImage, skip the ELF header, and stuff |
|
* a 32 byte header on the front. |
|
* |
|
* We use htonl, which is a network macro, to make sure we're doing |
|
* The Right Thing on an LE machine. It's non-obvious, but it should |
|
* work on anything BSD'ish. |
|
*/ |
|
|
|
#include <fcntl.h> |
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <string.h> |
|
#include <sys/stat.h> |
|
#include <unistd.h> |
|
#include <netinet/in.h> |
|
#ifdef __sun__ |
|
#include <inttypes.h> |
|
#else |
|
#include <stdint.h> |
|
#endif |
|
|
|
/* This gets tacked on the front of the image. There are also a few |
|
* bytes allocated after the _start label used by the boot rom (see |
|
* head.S for details). |
|
*/ |
|
typedef struct boot_block { |
|
uint32_t bb_magic; /* 0x0052504F */ |
|
uint32_t bb_dest; /* Target address of the image */ |
|
uint32_t bb_num_512blocks; /* Size, rounded-up, in 512 byte blks */ |
|
uint32_t bb_debug_flag; /* Run debugger or image after load */ |
|
uint32_t bb_entry_point; /* The image address to start */ |
|
uint32_t bb_checksum; /* 32 bit checksum including header */ |
|
uint32_t reserved[2]; |
|
} boot_block_t; |
|
|
|
#define IMGBLK 512 |
|
unsigned int tmpbuf[IMGBLK / sizeof(unsigned int)]; |
|
|
|
int main(int argc, char *argv[]) |
|
{ |
|
int in_fd, out_fd; |
|
int nblks, i; |
|
unsigned int cksum, *cp; |
|
struct stat st; |
|
boot_block_t bt; |
|
|
|
if (argc < 5) { |
|
fprintf(stderr, "usage: %s <zImage-file> <boot-image> <load address> <entry point>\n",argv[0]); |
|
exit(1); |
|
} |
|
|
|
if (stat(argv[1], &st) < 0) { |
|
perror("stat"); |
|
exit(2); |
|
} |
|
|
|
nblks = (st.st_size + IMGBLK) / IMGBLK; |
|
|
|
bt.bb_magic = htonl(0x0052504F); |
|
|
|
/* If we have the optional entry point parameter, use it */ |
|
bt.bb_dest = htonl(strtoul(argv[3], NULL, 0)); |
|
bt.bb_entry_point = htonl(strtoul(argv[4], NULL, 0)); |
|
|
|
/* We know these from the linker command. |
|
* ...and then move it up into memory a little more so the |
|
* relocation can happen. |
|
*/ |
|
bt.bb_num_512blocks = htonl(nblks); |
|
bt.bb_debug_flag = 0; |
|
|
|
bt.bb_checksum = 0; |
|
|
|
/* To be neat and tidy :-). |
|
*/ |
|
bt.reserved[0] = 0; |
|
bt.reserved[1] = 0; |
|
|
|
if ((in_fd = open(argv[1], O_RDONLY)) < 0) { |
|
perror("zImage open"); |
|
exit(3); |
|
} |
|
|
|
if ((out_fd = open(argv[2], (O_RDWR | O_CREAT | O_TRUNC), 0666)) < 0) { |
|
perror("bootfile open"); |
|
exit(3); |
|
} |
|
|
|
cksum = 0; |
|
cp = (void *)&bt; |
|
for (i = 0; i < sizeof(bt) / sizeof(unsigned int); i++) |
|
cksum += *cp++; |
|
|
|
/* Assume zImage is an ELF file, and skip the 64K header. |
|
*/ |
|
if (read(in_fd, tmpbuf, sizeof(tmpbuf)) != sizeof(tmpbuf)) { |
|
fprintf(stderr, "%s is too small to be an ELF image\n", |
|
argv[1]); |
|
exit(4); |
|
} |
|
|
|
if (tmpbuf[0] != htonl(0x7f454c46)) { |
|
fprintf(stderr, "%s is not an ELF image\n", argv[1]); |
|
exit(4); |
|
} |
|
|
|
if (lseek(in_fd, (64 * 1024), SEEK_SET) < 0) { |
|
fprintf(stderr, "%s failed to seek in ELF image\n", argv[1]); |
|
exit(4); |
|
} |
|
|
|
nblks -= (64 * 1024) / IMGBLK; |
|
|
|
/* And away we go...... |
|
*/ |
|
if (write(out_fd, &bt, sizeof(bt)) != sizeof(bt)) { |
|
perror("boot-image write"); |
|
exit(5); |
|
} |
|
|
|
while (nblks-- > 0) { |
|
if (read(in_fd, tmpbuf, sizeof(tmpbuf)) < 0) { |
|
perror("zImage read"); |
|
exit(5); |
|
} |
|
cp = tmpbuf; |
|
for (i = 0; i < sizeof(tmpbuf) / sizeof(unsigned int); i++) |
|
cksum += *cp++; |
|
if (write(out_fd, tmpbuf, sizeof(tmpbuf)) != sizeof(tmpbuf)) { |
|
perror("boot-image write"); |
|
exit(5); |
|
} |
|
} |
|
|
|
/* rewrite the header with the computed checksum. |
|
*/ |
|
bt.bb_checksum = htonl(cksum); |
|
if (lseek(out_fd, 0, SEEK_SET) < 0) { |
|
perror("rewrite seek"); |
|
exit(1); |
|
} |
|
if (write(out_fd, &bt, sizeof(bt)) != sizeof(bt)) { |
|
perror("boot-image rewrite"); |
|
exit(1); |
|
} |
|
|
|
exit(0); |
|
}
|
|
|