build.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. /*
  2. * linux/tools/build.c
  3. *
  4. * Copyright (C) 1991, 1992 Linus Torvalds
  5. */
  6. /*
  7. * This file builds a disk-image from three different files:
  8. *
  9. * - bootsect: exactly 512 bytes of 8086 machine code, loads the rest
  10. * - setup: 8086 machine code, sets up system parm
  11. * - system: 80386 code for actual system
  12. *
  13. * It does some checking that all files are of the correct type, and
  14. * just writes the result to stdout, removing headers and padding to
  15. * the right amount. It also writes some system data to stderr.
  16. */
  17. /*
  18. * Changes by tytso to allow root device specification
  19. * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
  20. * Cross compiling fixes by Gertjan van Wingerde, July 1996
  21. */
  22. #include <stdio.h> /* fprintf */
  23. #include <string.h>
  24. #include <stdlib.h> /* contains exit */
  25. #include <sys/types.h> /* unistd.h needs this */
  26. #include <sys/stat.h>
  27. #include <sys/sysmacros.h>
  28. #include <unistd.h> /* contains read/write */
  29. #include <fcntl.h>
  30. #include <errno.h>
  31. #define MINIX_HEADER 32
  32. #define N_MAGIC_OFFSET 1024
  33. #ifndef __BFD__
  34. static int GCC_HEADER = sizeof(struct exec);
  35. #endif
  36. #ifdef __BIG_KERNEL__
  37. #define SYS_SIZE 0xffff
  38. #else
  39. #define SYS_SIZE DEF_SYSSIZE
  40. #endif
  41. #define DEFAULT_MAJOR_ROOT 0
  42. #define DEFAULT_MINOR_ROOT 0
  43. /* max nr of sectors of setup: don't change unless you also change
  44. * bootsect etc */
  45. #define SETUP_SECTS 4
  46. #define STRINGIFY(x) #x
  47. typedef union {
  48. int i;
  49. long l;
  50. short s[2];
  51. char b[4];
  52. } conv;
  53. long intel_long(long l)
  54. {
  55. conv t;
  56. t.b[0] = l & 0xff; l >>= 8;
  57. t.b[1] = l & 0xff; l >>= 8;
  58. t.b[2] = l & 0xff; l >>= 8;
  59. t.b[3] = l & 0xff; l >>= 8;
  60. return t.l;
  61. }
  62. int intel_int(int i)
  63. {
  64. conv t;
  65. t.b[0] = i & 0xff; i >>= 8;
  66. t.b[1] = i & 0xff; i >>= 8;
  67. t.b[2] = i & 0xff; i >>= 8;
  68. t.b[3] = i & 0xff; i >>= 8;
  69. return t.i;
  70. }
  71. short intel_short(short l)
  72. {
  73. conv t;
  74. t.b[0] = l & 0xff; l >>= 8;
  75. t.b[1] = l & 0xff; l >>= 8;
  76. return t.s[0];
  77. }
  78. void die(const char * str)
  79. {
  80. fprintf(stderr,"%s\n",str);
  81. exit(1);
  82. }
  83. void usage(void)
  84. {
  85. die("Usage: build bootsect setup system [rootdev] [> image]");
  86. }
  87. int main(int argc, char ** argv)
  88. {
  89. int i,c,id,sz,tmp_int;
  90. unsigned long sys_size, tmp_long;
  91. char buf[1024];
  92. #ifndef __BFD__
  93. struct exec *ex = (struct exec *)buf;
  94. #endif
  95. char major_root, minor_root;
  96. struct stat sb;
  97. unsigned char setup_sectors;
  98. if ((argc < 4) || (argc > 5))
  99. usage();
  100. if (argc > 4) {
  101. if (!strcmp(argv[4], "CURRENT")) {
  102. if (stat("/", &sb)) {
  103. perror("/");
  104. die("Couldn't stat /");
  105. }
  106. major_root = major(sb.st_dev);
  107. minor_root = minor(sb.st_dev);
  108. } else if (strcmp(argv[4], "FLOPPY")) {
  109. if (stat(argv[4], &sb)) {
  110. perror(argv[4]);
  111. die("Couldn't stat root device.");
  112. }
  113. major_root = major(sb.st_rdev);
  114. minor_root = minor(sb.st_rdev);
  115. } else {
  116. major_root = 0;
  117. minor_root = 0;
  118. }
  119. } else {
  120. major_root = DEFAULT_MAJOR_ROOT;
  121. minor_root = DEFAULT_MINOR_ROOT;
  122. }
  123. fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
  124. for (i=0;i<sizeof buf; i++) buf[i]=0;
  125. if ((id=open(argv[1],O_RDONLY,0))<0)
  126. die("Unable to open 'boot'");
  127. if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)
  128. die("Unable to read header of 'boot'");
  129. if (((long *) buf)[0]!=intel_long(0x04100301))
  130. die("Non-Minix header of 'boot'");
  131. if (((long *) buf)[1]!=intel_long(MINIX_HEADER))
  132. die("Non-Minix header of 'boot'");
  133. if (((long *) buf)[3] != 0)
  134. die("Illegal data segment in 'boot'");
  135. if (((long *) buf)[4] != 0)
  136. die("Illegal bss in 'boot'");
  137. if (((long *) buf)[5] != 0)
  138. die("Non-Minix header of 'boot'");
  139. if (((long *) buf)[7] != 0)
  140. die("Illegal symbol table in 'boot'");
  141. i=read(id,buf,sizeof buf);
  142. fprintf(stderr,"Boot sector %d bytes.\n",i);
  143. if (i != 512)
  144. die("Boot block must be exactly 512 bytes");
  145. if ((*(unsigned short *)(buf+510)) != (unsigned short)intel_short(0xAA55))
  146. die("Boot block hasn't got boot flag (0xAA55)");
  147. buf[508] = (char) minor_root;
  148. buf[509] = (char) major_root;
  149. i=write(1,buf,512);
  150. if (i!=512)
  151. die("Write call failed");
  152. close (id);
  153. if ((id=open(argv[2],O_RDONLY,0))<0)
  154. die("Unable to open 'setup'");
  155. if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)
  156. die("Unable to read header of 'setup'");
  157. if (((long *) buf)[0]!=intel_long(0x04100301))
  158. die("Non-Minix header of 'setup'");
  159. if (((long *) buf)[1]!=intel_long(MINIX_HEADER))
  160. die("Non-Minix header of 'setup'");
  161. if (((long *) buf)[3] != 0)
  162. die("Illegal data segment in 'setup'");
  163. if (((long *) buf)[4] != 0)
  164. die("Illegal bss in 'setup'");
  165. if (((long *) buf)[5] != 0)
  166. die("Non-Minix header of 'setup'");
  167. if (((long *) buf)[7] != 0)
  168. die("Illegal symbol table in 'setup'");
  169. for (i=0 ; (c=read(id,buf,sizeof buf))>0 ; i+=c )
  170. #ifdef __BIG_KERNEL__
  171. {
  172. if (!i) {
  173. /* Working with memcpy because of alignment constraints
  174. on Sparc - Gertjan */
  175. memcpy(&tmp_long, &buf[2], sizeof(long));
  176. if (tmp_long != intel_long(0x53726448) )
  177. die("Wrong magic in loader header of 'setup'");
  178. memcpy(&tmp_int, &buf[6], sizeof(int));
  179. if (tmp_int < intel_int(0x200))
  180. die("Wrong version of loader header of 'setup'");
  181. buf[0x11] = 1; /* LOADED_HIGH */
  182. tmp_long = intel_long(0x100000);
  183. memcpy(&buf[0x14], &tmp_long, sizeof(long)); /* code32_start */
  184. }
  185. #endif
  186. if (write(1,buf,c)!=c)
  187. die("Write call failed");
  188. #ifdef __BIG_KERNEL__
  189. }
  190. #endif
  191. if (c != 0)
  192. die("read-error on 'setup'");
  193. close (id);
  194. setup_sectors = (unsigned char)((i + 511) / 512);
  195. /* for compatibility with LILO */
  196. if (setup_sectors < SETUP_SECTS)
  197. setup_sectors = SETUP_SECTS;
  198. fprintf(stderr,"Setup is %d bytes.\n",i);
  199. for (c=0 ; c<sizeof(buf) ; c++)
  200. buf[c] = '\0';
  201. while (i < setup_sectors * 512) {
  202. c = setup_sectors * 512 - i;
  203. if (c > sizeof(buf))
  204. c = sizeof(buf);
  205. if (write(1,buf,c) != c)
  206. die("Write call failed");
  207. i += c;
  208. }
  209. if ((id=open(argv[3],O_RDONLY,0))<0)
  210. die("Unable to open 'system'");
  211. #ifndef __BFD__
  212. if (read(id,buf,GCC_HEADER) != GCC_HEADER)
  213. die("Unable to read header of 'system'");
  214. if (N_MAGIC(*ex) == ZMAGIC) {
  215. GCC_HEADER = N_MAGIC_OFFSET;
  216. lseek(id, GCC_HEADER, SEEK_SET);
  217. } else if (N_MAGIC(*ex) != QMAGIC)
  218. die("Non-GCC header of 'system'");
  219. fprintf(stderr,"System is %d kB (%d kB code, %d kB data and %d kB bss)\n",
  220. (ex->a_text+ex->a_data+ex->a_bss)/1024,
  221. ex->a_text /1024,
  222. ex->a_data /1024,
  223. ex->a_bss /1024);
  224. sz = N_SYMOFF(*ex) - GCC_HEADER + 4;
  225. #else
  226. if (fstat (id, &sb)) {
  227. perror ("fstat");
  228. die ("Unable to stat 'system'");
  229. }
  230. sz = sb.st_size;
  231. fprintf (stderr, "System is %d kB\n", sz/1024);
  232. #endif
  233. sys_size = (sz + 15) / 16;
  234. if (sys_size > SYS_SIZE)
  235. die("System is too big");
  236. while (sz > 0) {
  237. int l, n;
  238. l = sz;
  239. if (l > sizeof(buf))
  240. l = sizeof(buf);
  241. if ((n=read(id, buf, l)) != l) {
  242. if (n == -1)
  243. perror(argv[1]);
  244. else
  245. fprintf(stderr, "Unexpected EOF\n");
  246. die("Can't read 'system'");
  247. }
  248. if (write(1, buf, l) != l)
  249. die("Write failed");
  250. sz -= l;
  251. }
  252. close(id);
  253. if (lseek(1, 497, 0) == 497) {
  254. if (write(1, &setup_sectors, 1) != 1)
  255. die("Write of setup sectors failed");
  256. }
  257. if (lseek(1,500,0) == 500) {
  258. buf[0] = (sys_size & 0xff);
  259. buf[1] = ((sys_size >> 8) & 0xff);
  260. if (write(1, buf, 2) != 2)
  261. die("Write failed");
  262. }
  263. return(0);
  264. }