Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Makes a tree bootable image for IBM Evaluation boards.
0004  * Basically, just take a zImage, skip the ELF header, and stuff
0005  * a 32 byte header on the front.
0006  *
0007  * We use htonl, which is a network macro, to make sure we're doing
0008  * The Right Thing on an LE machine.  It's non-obvious, but it should
0009  * work on anything BSD'ish.
0010  */
0011 
0012 #include <fcntl.h>
0013 #include <stdio.h>
0014 #include <stdlib.h>
0015 #include <string.h>
0016 #include <sys/stat.h>
0017 #include <unistd.h>
0018 #include <netinet/in.h>
0019 #ifdef __sun__
0020 #include <inttypes.h>
0021 #else
0022 #include <stdint.h>
0023 #endif
0024 
0025 /* This gets tacked on the front of the image.  There are also a few
0026  * bytes allocated after the _start label used by the boot rom (see
0027  * head.S for details).
0028  */
0029 typedef struct boot_block {
0030     uint32_t bb_magic;      /* 0x0052504F */
0031     uint32_t bb_dest;       /* Target address of the image */
0032     uint32_t bb_num_512blocks;  /* Size, rounded-up, in 512 byte blks */
0033     uint32_t bb_debug_flag; /* Run debugger or image after load */
0034     uint32_t bb_entry_point;    /* The image address to start */
0035     uint32_t bb_checksum;   /* 32 bit checksum including header */
0036     uint32_t reserved[2];
0037 } boot_block_t;
0038 
0039 #define IMGBLK  512
0040 unsigned int    tmpbuf[IMGBLK / sizeof(unsigned int)];
0041 
0042 int main(int argc, char *argv[])
0043 {
0044     int in_fd, out_fd;
0045     int nblks, i;
0046     unsigned int    cksum, *cp;
0047     struct  stat    st;
0048     boot_block_t    bt;
0049 
0050     if (argc < 5) {
0051         fprintf(stderr, "usage: %s <zImage-file> <boot-image> <load address> <entry point>\n",argv[0]);
0052         exit(1);
0053     }
0054 
0055     if (stat(argv[1], &st) < 0) {
0056         perror("stat");
0057         exit(2);
0058     }
0059 
0060     nblks = (st.st_size + IMGBLK) / IMGBLK;
0061 
0062     bt.bb_magic = htonl(0x0052504F);
0063 
0064     /* If we have the optional entry point parameter, use it */
0065     bt.bb_dest = htonl(strtoul(argv[3], NULL, 0));
0066     bt.bb_entry_point = htonl(strtoul(argv[4], NULL, 0));
0067 
0068     /* We know these from the linker command.
0069      * ...and then move it up into memory a little more so the
0070      * relocation can happen.
0071      */
0072     bt.bb_num_512blocks = htonl(nblks);
0073     bt.bb_debug_flag = 0;
0074 
0075     bt.bb_checksum = 0;
0076 
0077     /* To be neat and tidy :-).
0078     */
0079     bt.reserved[0] = 0;
0080     bt.reserved[1] = 0;
0081 
0082     if ((in_fd = open(argv[1], O_RDONLY)) < 0) {
0083         perror("zImage open");
0084         exit(3);
0085     }
0086 
0087     if ((out_fd = open(argv[2], (O_RDWR | O_CREAT | O_TRUNC), 0666)) < 0) {
0088         perror("bootfile open");
0089         exit(3);
0090     }
0091 
0092     cksum = 0;
0093     cp = (void *)&bt;
0094     for (i = 0; i < sizeof(bt) / sizeof(unsigned int); i++)
0095         cksum += *cp++;
0096 
0097     /* Assume zImage is an ELF file, and skip the 64K header.
0098     */
0099     if (read(in_fd, tmpbuf, sizeof(tmpbuf)) != sizeof(tmpbuf)) {
0100         fprintf(stderr, "%s is too small to be an ELF image\n",
0101                 argv[1]);
0102         exit(4);
0103     }
0104 
0105     if (tmpbuf[0] != htonl(0x7f454c46)) {
0106         fprintf(stderr, "%s is not an ELF image\n", argv[1]);
0107         exit(4);
0108     }
0109 
0110     if (lseek(in_fd, (64 * 1024), SEEK_SET) < 0) {
0111         fprintf(stderr, "%s failed to seek in ELF image\n", argv[1]);
0112         exit(4);
0113     }
0114 
0115     nblks -= (64 * 1024) / IMGBLK;
0116 
0117     /* And away we go......
0118     */
0119     if (write(out_fd, &bt, sizeof(bt)) != sizeof(bt)) {
0120         perror("boot-image write");
0121         exit(5);
0122     }
0123 
0124     while (nblks-- > 0) {
0125         if (read(in_fd, tmpbuf, sizeof(tmpbuf)) < 0) {
0126             perror("zImage read");
0127             exit(5);
0128         }
0129         cp = tmpbuf;
0130         for (i = 0; i < sizeof(tmpbuf) / sizeof(unsigned int); i++)
0131             cksum += *cp++;
0132         if (write(out_fd, tmpbuf, sizeof(tmpbuf)) != sizeof(tmpbuf)) {
0133             perror("boot-image write");
0134             exit(5);
0135         }
0136     }
0137 
0138     /* rewrite the header with the computed checksum.
0139     */
0140     bt.bb_checksum = htonl(cksum);
0141     if (lseek(out_fd, 0, SEEK_SET) < 0) {
0142         perror("rewrite seek");
0143         exit(1);
0144     }
0145     if (write(out_fd, &bt, sizeof(bt)) != sizeof(bt)) {
0146         perror("boot-image rewrite");
0147         exit(1);
0148     }
0149 
0150     exit(0);
0151 }