1*54fd6939SJiyong Park /*
2*54fd6939SJiyong Park * Copyright (c) 2019, Remi Pommarel <[email protected]>
3*54fd6939SJiyong Park *
4*54fd6939SJiyong Park * SPDX-License-Identifier: BSD-3-Clause
5*54fd6939SJiyong Park */
6*54fd6939SJiyong Park #include <stdlib.h>
7*54fd6939SJiyong Park #include <stdio.h>
8*54fd6939SJiyong Park #include <fcntl.h>
9*54fd6939SJiyong Park #include <unistd.h>
10*54fd6939SJiyong Park #include <stdint.h>
11*54fd6939SJiyong Park #include <endian.h>
12*54fd6939SJiyong Park
13*54fd6939SJiyong Park #define DEFAULT_PROGNAME "doimage"
14*54fd6939SJiyong Park #define PROGNAME(argc, argv) (((argc) >= 1) ? ((argv)[0]) : DEFAULT_PROGNAME)
15*54fd6939SJiyong Park
16*54fd6939SJiyong Park #define BL31_MAGIC 0x12348765
17*54fd6939SJiyong Park #define BL31_LOADADDR 0x05100000
18*54fd6939SJiyong Park #define BUFLEN 512
19*54fd6939SJiyong Park
usage(char const * prog)20*54fd6939SJiyong Park static inline void usage(char const *prog)
21*54fd6939SJiyong Park {
22*54fd6939SJiyong Park fprintf(stderr, "Usage: %s <bl31.bin> <bl31.img>\n", prog);
23*54fd6939SJiyong Park }
24*54fd6939SJiyong Park
fdwrite(int fd,uint8_t * data,size_t len)25*54fd6939SJiyong Park static inline int fdwrite(int fd, uint8_t *data, size_t len)
26*54fd6939SJiyong Park {
27*54fd6939SJiyong Park ssize_t nr;
28*54fd6939SJiyong Park size_t l;
29*54fd6939SJiyong Park int ret = -1;
30*54fd6939SJiyong Park
31*54fd6939SJiyong Park for (l = 0; l < len; l += nr) {
32*54fd6939SJiyong Park nr = write(fd, data + l, len - l);
33*54fd6939SJiyong Park if (nr < 0) {
34*54fd6939SJiyong Park perror("Cannot write to bl31.img");
35*54fd6939SJiyong Park goto out;
36*54fd6939SJiyong Park }
37*54fd6939SJiyong Park }
38*54fd6939SJiyong Park
39*54fd6939SJiyong Park ret = 0;
40*54fd6939SJiyong Park out:
41*54fd6939SJiyong Park return ret;
42*54fd6939SJiyong Park }
43*54fd6939SJiyong Park
main(int argc,char ** argv)44*54fd6939SJiyong Park int main(int argc, char **argv)
45*54fd6939SJiyong Park {
46*54fd6939SJiyong Park int fin, fout, ret = -1;
47*54fd6939SJiyong Park ssize_t len;
48*54fd6939SJiyong Park uint32_t data;
49*54fd6939SJiyong Park uint8_t buf[BUFLEN];
50*54fd6939SJiyong Park
51*54fd6939SJiyong Park if (argc != 3) {
52*54fd6939SJiyong Park usage(PROGNAME(argc, argv));
53*54fd6939SJiyong Park goto out;
54*54fd6939SJiyong Park }
55*54fd6939SJiyong Park
56*54fd6939SJiyong Park fin = open(argv[1], O_RDONLY);
57*54fd6939SJiyong Park if (fin < 0) {
58*54fd6939SJiyong Park perror("Cannot open bl31.bin");
59*54fd6939SJiyong Park goto out;
60*54fd6939SJiyong Park }
61*54fd6939SJiyong Park
62*54fd6939SJiyong Park fout = open(argv[2], O_WRONLY | O_CREAT, 0660);
63*54fd6939SJiyong Park if (fout < 0) {
64*54fd6939SJiyong Park perror("Cannot open bl31.img");
65*54fd6939SJiyong Park goto closefin;
66*54fd6939SJiyong Park }
67*54fd6939SJiyong Park
68*54fd6939SJiyong Park data = htole32(BL31_MAGIC);
69*54fd6939SJiyong Park if (fdwrite(fout, (uint8_t *)&data, sizeof(data)) < 0)
70*54fd6939SJiyong Park goto closefout;
71*54fd6939SJiyong Park
72*54fd6939SJiyong Park lseek(fout, 8, SEEK_SET);
73*54fd6939SJiyong Park data = htole32(BL31_LOADADDR);
74*54fd6939SJiyong Park if (fdwrite(fout, (uint8_t *)&data, sizeof(data)) < 0)
75*54fd6939SJiyong Park goto closefout;
76*54fd6939SJiyong Park
77*54fd6939SJiyong Park lseek(fout, 0x200, SEEK_SET);
78*54fd6939SJiyong Park while ((len = read(fin, buf, sizeof(buf))) > 0)
79*54fd6939SJiyong Park if (fdwrite(fout, buf, len) < 0)
80*54fd6939SJiyong Park goto closefout;
81*54fd6939SJiyong Park if (len < 0) {
82*54fd6939SJiyong Park perror("Cannot read bl31.bin");
83*54fd6939SJiyong Park goto closefout;
84*54fd6939SJiyong Park }
85*54fd6939SJiyong Park
86*54fd6939SJiyong Park ret = 0;
87*54fd6939SJiyong Park
88*54fd6939SJiyong Park closefout:
89*54fd6939SJiyong Park close(fout);
90*54fd6939SJiyong Park closefin:
91*54fd6939SJiyong Park close(fin);
92*54fd6939SJiyong Park out:
93*54fd6939SJiyong Park return ret;
94*54fd6939SJiyong Park }
95