jh7110_uboot_spl.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #define _GNU_SOURCE
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <stdint.h>
  8. #include <string.h>
  9. #include <unistd.h>
  10. #include <endian.h>
  11. #include <errno.h>
  12. #include <limits.h>
  13. #define NOSIZE ((size_t)-1)
  14. extern uint32_t crc32(uint32_t iv, uint32_t sv, const void *data, size_t n);
  15. extern uint32_t crc32_final(uint32_t iv);
  16. /* all uint32_t ends up little endian in output header */
  17. struct __attribute__((__packed__)) ubootsplhdr {
  18. uint32_t sofs; /* offset of "second?" header: 0x240, dunno */
  19. uint32_t bofs; /* SBL_BAK_OFFSET: Offset of backup SBL from Flash info start (from input_sbl_normal.cfg) */
  20. uint8_t zro2[636];
  21. uint32_t vers; /* version: shall be 0x01010101
  22. * (from https://doc-en.rvspace.org/VisionFive2/SWTRM/VisionFive2_SW_TRM/create_spl.html) */
  23. uint32_t fsiz; /* u-boot-spl.bin size in bytes */
  24. uint32_t res1; /* unknown, 0x400 (00 04 00 00) currently */
  25. uint32_t crcs; /* CRC32 of u-boot-spl.bin */
  26. uint8_t zro3[364];
  27. };
  28. static struct ubootsplhdr ubsplhdr;
  29. static char ubootspl[131072-0x400];
  30. static char outpath[PATH_MAX];
  31. #define DEFVERSID 0x01010101
  32. static void xerror(int errnoval, const char *s)
  33. {
  34. if (errnoval) perror(s);
  35. else fprintf(stderr, "%s\n", s);
  36. exit(2);
  37. }
  38. static void usage(void)
  39. {
  40. printf("usage: jh7110_uboot_spl u-boot-spl.bin [version]\n");
  41. printf("u-boot-spl.bin is path to input U-Boot SPL file\n");
  42. printf("if version specified, shall be 0x01010101\n");
  43. printf("output will be written to u-boot-spl.bin.out\n");
  44. exit(1);
  45. }
  46. int main(int argc, char **argv)
  47. {
  48. int fd;
  49. uint32_t v;
  50. size_t sz;
  51. if (argc < 2) usage();
  52. fd = open(argv[1], O_RDONLY);
  53. if (fd == -1) xerror(errno, argv[1]);
  54. ubsplhdr.sofs = htole32(0x240U);
  55. ubsplhdr.bofs = htole32(0x200000U);
  56. ubsplhdr.res1 = htole32(0x400U);
  57. if (argc >= 3) {
  58. v = (uint32_t)strtoul(argv[2], NULL, 16);
  59. v = htole32(v);
  60. ubsplhdr.vers = v;
  61. }
  62. else ubsplhdr.vers = htole32(DEFVERSID);
  63. sz = (size_t)read(fd, ubootspl, sizeof(ubootspl));
  64. if (sz == NOSIZE) xerror(errno, argv[1]);
  65. if (sz >= (sizeof(ubootspl) - sizeof(struct ubootsplhdr)))
  66. xerror(0, "File too large! Please rebuild your SPL with -Os. Maximum allowed size is 130048 bytes.");
  67. v = htole32((uint32_t)sz);
  68. ubsplhdr.fsiz = v;
  69. close(fd);
  70. snprintf(outpath, sizeof(outpath), "%s.out", argv[1]);
  71. fd = creat(outpath, 0666);
  72. if (fd == -1) xerror(errno, outpath);
  73. v = crc32(~0U, 0x04c11db7U, ubootspl, sz);
  74. v = crc32_final(v);
  75. v = htole32(v);
  76. ubsplhdr.crcs = v;
  77. write(fd, &ubsplhdr, sizeof(struct ubootsplhdr));
  78. write(fd, ubootspl, sz);
  79. close(fd);
  80. printf("SPL written to %s successfully.\n", outpath);
  81. return 0;
  82. }