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

Linux/Unix编程

开发平台:

Unix_Linux

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