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 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 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 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