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