addinitrd.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * addinitrd - program to add a initrd image to an ecoff kernel
  3. *
  4. * (C) 1999 Thomas Bogendoerfer
  5. * minor modifications, cleanup: Guido Guenther <agx@sigxcpu.org>
  6. * further cleanup: Maciej W. Rozycki
  7. */
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10. #include <fcntl.h>
  11. #include <unistd.h>
  12. #include <stdio.h>
  13. #include <netinet/in.h>
  14. #include "ecoff.h"
  15. #define MIPS_PAGE_SIZE 4096
  16. #define MIPS_PAGE_MASK (MIPS_PAGE_SIZE-1)
  17. #define swab16(x) \
  18. ((unsigned short)( \
  19. (((unsigned short)(x) & (unsigned short)0x00ffU) << 8) | \
  20. (((unsigned short)(x) & (unsigned short)0xff00U) >> 8) ))
  21. #define swab32(x) \
  22. ((unsigned int)( \
  23. (((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) | \
  24. (((unsigned int)(x) & (unsigned int)0x0000ff00UL) << 8) | \
  25. (((unsigned int)(x) & (unsigned int)0x00ff0000UL) >> 8) | \
  26. (((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24) ))
  27. #define SWAB(a) (swab ? swab32(a) : (a))
  28. void die(char *s)
  29. {
  30. perror(s);
  31. exit(1);
  32. }
  33. int main(int argc, char *argv[])
  34. {
  35. int fd_vmlinux, fd_initrd, fd_outfile;
  36. FILHDR efile;
  37. AOUTHDR eaout;
  38. SCNHDR esecs[3];
  39. struct stat st;
  40. char buf[1024];
  41. unsigned long loadaddr;
  42. unsigned long initrd_header[2];
  43. int i, cnt;
  44. int swab = 0;
  45. if (argc != 4) {
  46. printf("Usage: %s <vmlinux> <initrd> <outfile>\n", argv[0]);
  47. exit(1);
  48. }
  49. if ((fd_vmlinux = open (argv[1], O_RDONLY)) < 0)
  50. die("open vmlinux");
  51. if (read (fd_vmlinux, &efile, sizeof efile) != sizeof efile)
  52. die("read file header");
  53. if (read (fd_vmlinux, &eaout, sizeof eaout) != sizeof eaout)
  54. die("read aout header");
  55. if (read (fd_vmlinux, esecs, sizeof esecs) != sizeof esecs)
  56. die("read section headers");
  57. /*
  58. * check whether the file is good for us
  59. */
  60. /* TBD */
  61. /*
  62. * check, if we have to swab words
  63. */
  64. if (ntohs(0xaa55) == 0xaa55) {
  65. if (efile.f_magic == swab16(MIPSELMAGIC))
  66. swab = 1;
  67. } else {
  68. if (efile.f_magic == swab16(MIPSEBMAGIC))
  69. swab = 1;
  70. }
  71. /* make sure we have an empty data segment for the initrd */
  72. if (eaout.dsize || esecs[1].s_size) {
  73. fprintf(stderr, "Data segment not empty. Giving up!\n");
  74. exit(1);
  75. }
  76. if ((fd_initrd = open (argv[2], O_RDONLY)) < 0)
  77. die("open initrd");
  78. if (fstat (fd_initrd, &st) < 0)
  79. die("fstat initrd");
  80. loadaddr = ((SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size)
  81. + MIPS_PAGE_SIZE-1) & ~MIPS_PAGE_MASK) - 8;
  82. if (loadaddr < (SWAB(esecs[2].s_vaddr) + SWAB(esecs[2].s_size)))
  83. loadaddr += MIPS_PAGE_SIZE;
  84. initrd_header[0] = SWAB(0x494E5244);
  85. initrd_header[1] = SWAB(st.st_size);
  86. eaout.dsize = esecs[1].s_size = initrd_header[1] = SWAB(st.st_size+8);
  87. eaout.data_start = esecs[1].s_vaddr = esecs[1].s_paddr = SWAB(loadaddr);
  88. if ((fd_outfile = open (argv[3], O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0)
  89. die("open outfile");
  90. if (write (fd_outfile, &efile, sizeof efile) != sizeof efile)
  91. die("write file header");
  92. if (write (fd_outfile, &eaout, sizeof eaout) != sizeof eaout)
  93. die("write aout header");
  94. if (write (fd_outfile, esecs, sizeof esecs) != sizeof esecs)
  95. die("write section headers");
  96. /* skip padding */
  97. if(lseek(fd_vmlinux, SWAB(esecs[0].s_scnptr), SEEK_SET) == (off_t)-1)
  98. die("lseek vmlinux");
  99. if(lseek(fd_outfile, SWAB(esecs[0].s_scnptr), SEEK_SET) == (off_t)-1)
  100. die("lseek outfile");
  101. /* copy text segment */
  102. cnt = SWAB(eaout.tsize);
  103. while (cnt) {
  104. if ((i = read (fd_vmlinux, buf, sizeof buf)) <= 0)
  105. die("read vmlinux");
  106. if (write (fd_outfile, buf, i) != i)
  107. die("write vmlinux");
  108. cnt -= i;
  109. }
  110. if (write (fd_outfile, initrd_header, sizeof initrd_header) != sizeof initrd_header)
  111. die("write initrd header");
  112. while ((i = read (fd_initrd, buf, sizeof buf)) > 0)
  113. if (write (fd_outfile, buf, i) != i)
  114. die("write initrd");
  115. close(fd_vmlinux);
  116. close(fd_initrd);
  117. return 0;
  118. }