mktree.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:3k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * BK Id: %F% %I% %G% %U% %#%
  3.  * 
  4.  * Makes a tree bootable image for IBM Evaluation boards.
  5.  * Basically, just take a zImage, skip the ELF header, and stuff
  6.  * a 32 byte header on the front.
  7.  *
  8.  * We use htonl, which is a network macro, to make sure we're doing
  9.  * The Right Thing on an LE machine.  It's non-obvious, but it should
  10.  * work on anything BSD'ish.
  11.  */
  12. #include <fcntl.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <sys/stat.h>
  17. #include <unistd.h>
  18. #include <netinet/in.h>
  19. /* This gets tacked on the front of the image.  There are also a few
  20.  * bytes allocated after the _start label used by the boot rom (see
  21.  * head.S for details).
  22.  */
  23. typedef struct boot_block {
  24. unsigned long bb_magic; /* 0x0052504F */
  25. unsigned long bb_dest; /* Target address of the image */
  26. unsigned long bb_num_512blocks; /* Size, rounded-up, in 512 byte blks */
  27. unsigned long bb_debug_flag; /* Run debugger or image after load */
  28. unsigned long bb_entry_point; /* The image address to start */
  29. unsigned long bb_checksum; /* 32 bit checksum including header */
  30. unsigned long reserved[2];
  31. } boot_block_t;
  32. #define IMGBLK 512
  33. char tmpbuf[IMGBLK];
  34. int main(int argc, char *argv[])
  35. {
  36. int in_fd, out_fd;
  37. int nblks, i;
  38. uint cksum, *cp;
  39. struct stat st;
  40. boot_block_t bt;
  41. if (argc < 3) {
  42. fprintf(stderr, "usage: %s <zImage-file> <boot-image> [entry-point]n",argv[0]);
  43. exit(1);
  44. }
  45. if (stat(argv[1], &st) < 0) {
  46. perror("stat");
  47. exit(2);
  48. }
  49. nblks = (st.st_size + IMGBLK) / IMGBLK;
  50. bt.bb_magic = htonl(0x0052504F);
  51. /* If we have the optional entry point parameter, use it */
  52. if (argc == 4)
  53. bt.bb_dest = bt.bb_entry_point = htonl(strtoul(argv[3], NULL, 0));
  54. else
  55. bt.bb_dest = bt.bb_entry_point = htonl(0x500000);
  56. /* We know these from the linker command.
  57.  * ...and then move it up into memory a little more so the
  58.  * relocation can happen.
  59.  */
  60. bt.bb_num_512blocks = htonl(nblks);
  61. bt.bb_debug_flag = 0;
  62. bt.bb_checksum = 0;
  63. /* To be neat and tidy :-).
  64. */
  65. bt.reserved[0] = 0;
  66. bt.reserved[1] = 0;
  67. if ((in_fd = open(argv[1], O_RDONLY)) < 0) {
  68. perror("zImage open");
  69. exit(3);
  70. }
  71. if ((out_fd = open(argv[2], (O_RDWR | O_CREAT | O_TRUNC), 0666)) < 0) {
  72. perror("bootfile open");
  73. exit(3);
  74. }
  75. cksum = 0;
  76. cp = (uint *)&bt;
  77. for (i=0; i<sizeof(bt)/sizeof(uint); i++)
  78. cksum += *cp++;
  79. /* Assume zImage is an ELF file, and skip the 64K header.
  80. */
  81. if (read(in_fd, tmpbuf, IMGBLK) != IMGBLK) {
  82. fprintf(stderr, "%s is too small to be an ELF imagen",
  83. argv[1]);
  84. exit(4);
  85. }
  86. if ((*(uint *)tmpbuf) != htonl(0x7f454c46)) {
  87. fprintf(stderr, "%s is not an ELF imagen", argv[1]);
  88. exit(4);
  89. }
  90. if (lseek(in_fd, (64 * 1024), SEEK_SET) < 0) {
  91. fprintf(stderr, "%s failed to seek in ELF imagen", argv[1]);
  92. exit(4);
  93. }
  94. nblks -= (64 * 1024) / IMGBLK;
  95. /* And away we go......
  96. */
  97. if (write(out_fd, &bt, sizeof(bt)) != sizeof(bt)) {
  98. perror("boot-image write");
  99. exit(5);
  100. }
  101. while (nblks-- > 0) {
  102. if (read(in_fd, tmpbuf, IMGBLK) < 0) {
  103. perror("zImage read");
  104. exit(5);
  105. }
  106. cp = (uint *)tmpbuf;
  107. for (i=0; i<sizeof(tmpbuf)/sizeof(uint); i++)
  108. cksum += *cp++;
  109. if (write(out_fd, tmpbuf, sizeof(tmpbuf)) != sizeof(tmpbuf)) {
  110. perror("boot-image write");
  111. exit(5);
  112. }
  113. }
  114. /* rewrite the header with the computed checksum.
  115. */
  116. bt.bb_checksum = htonl(cksum);
  117. if (lseek(out_fd, 0, SEEK_SET) < 0) {
  118. perror("rewrite seek");
  119. exit(1);
  120. }
  121. if (write(out_fd, &bt, sizeof(bt)) != sizeof(bt)) {
  122. perror("boot-image rewrite");
  123. exit(1);
  124. }
  125. exit(0);
  126. }