build.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. * Copyright (C) 1991, 1992 Linus Torvalds
  3. * Copyright (C) 1997 Martin Mares
  4. * Copyright (C) 2007 H. Peter Anvin
  5. */
  6. /*
  7. * This file builds a disk-image from two different files:
  8. *
  9. * - setup: 8086 machine code, sets up system parm
  10. * - system: 80386 code for actual system
  11. *
  12. * It does some checking that all files are of the correct type, and
  13. * just writes the result to stdout, removing headers and padding to
  14. * the right amount. It also writes some system data to stderr.
  15. */
  16. /*
  17. * Changes by tytso to allow root device specification
  18. * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
  19. * Cross compiling fixes by Gertjan van Wingerde, July 1996
  20. * Rewritten by Martin Mares, April 1997
  21. * Substantially overhauled by H. Peter Anvin, April 2007
  22. */
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <stdlib.h>
  26. #include <stdarg.h>
  27. #include <sys/types.h>
  28. #include <sys/stat.h>
  29. #include <sys/sysmacros.h>
  30. #include <unistd.h>
  31. #include <fcntl.h>
  32. #include <sys/mman.h>
  33. #include <asm/boot.h>
  34. typedef unsigned char u8;
  35. typedef unsigned short u16;
  36. typedef unsigned long u32;
  37. #define DEFAULT_MAJOR_ROOT 0
  38. #define DEFAULT_MINOR_ROOT 0
  39. /* Minimal number of setup sectors */
  40. #define SETUP_SECT_MIN 5
  41. #define SETUP_SECT_MAX 64
  42. /* This must be large enough to hold the entire setup */
  43. u8 buf[SETUP_SECT_MAX*512];
  44. int is_big_kernel;
  45. static void die(const char * str, ...)
  46. {
  47. va_list args;
  48. va_start(args, str);
  49. vfprintf(stderr, str, args);
  50. fputc('\n', stderr);
  51. exit(1);
  52. }
  53. static void usage(void)
  54. {
  55. die("Usage: build [-b] setup system [rootdev] [> image]");
  56. }
  57. int main(int argc, char ** argv)
  58. {
  59. unsigned int i, sz, setup_sectors;
  60. int c;
  61. u32 sys_size;
  62. u8 major_root, minor_root;
  63. struct stat sb;
  64. FILE *file;
  65. int fd;
  66. void *kernel;
  67. if (argc > 2 && !strcmp(argv[1], "-b"))
  68. {
  69. is_big_kernel = 1;
  70. argc--, argv++;
  71. }
  72. if ((argc < 3) || (argc > 4))
  73. usage();
  74. if (argc > 3) {
  75. if (!strcmp(argv[3], "CURRENT")) {
  76. if (stat("/", &sb)) {
  77. perror("/");
  78. die("Couldn't stat /");
  79. }
  80. major_root = major(sb.st_dev);
  81. minor_root = minor(sb.st_dev);
  82. } else if (strcmp(argv[3], "FLOPPY")) {
  83. if (stat(argv[3], &sb)) {
  84. perror(argv[3]);
  85. die("Couldn't stat root device.");
  86. }
  87. major_root = major(sb.st_rdev);
  88. minor_root = minor(sb.st_rdev);
  89. } else {
  90. major_root = 0;
  91. minor_root = 0;
  92. }
  93. } else {
  94. major_root = DEFAULT_MAJOR_ROOT;
  95. minor_root = DEFAULT_MINOR_ROOT;
  96. }
  97. fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
  98. /* Copy the setup code */
  99. file = fopen(argv[1], "r");
  100. if (!file)
  101. die("Unable to open `%s': %m", argv[1]);
  102. c = fread(buf, 1, sizeof(buf), file);
  103. if (ferror(file))
  104. die("read-error on `setup'");
  105. if (c < 1024)
  106. die("The setup must be at least 1024 bytes");
  107. if (buf[510] != 0x55 || buf[511] != 0xaa)
  108. die("Boot block hasn't got boot flag (0xAA55)");
  109. fclose(file);
  110. /* Pad unused space with zeros */
  111. setup_sectors = (c + 511) / 512;
  112. if (setup_sectors < SETUP_SECT_MIN)
  113. setup_sectors = SETUP_SECT_MIN;
  114. i = setup_sectors*512;
  115. memset(buf+c, 0, i-c);
  116. /* Set the default root device */
  117. buf[508] = minor_root;
  118. buf[509] = major_root;
  119. fprintf(stderr, "Setup is %d bytes (padded to %d bytes).\n", c, i);
  120. /* Open and stat the kernel file */
  121. fd = open(argv[2], O_RDONLY);
  122. if (fd < 0)
  123. die("Unable to open `%s': %m", argv[2]);
  124. if (fstat(fd, &sb))
  125. die("Unable to stat `%s': %m", argv[2]);
  126. sz = sb.st_size;
  127. fprintf (stderr, "System is %d kB\n", (sz+1023)/1024);
  128. kernel = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
  129. if (kernel == MAP_FAILED)
  130. die("Unable to mmap '%s': %m", argv[2]);
  131. sys_size = (sz + 15) / 16;
  132. if (!is_big_kernel && sys_size > DEF_SYSSIZE)
  133. die("System is too big. Try using bzImage or modules.");
  134. /* Patch the setup code with the appropriate size parameters */
  135. buf[0x1f1] = setup_sectors-1;
  136. buf[0x1f4] = sys_size;
  137. buf[0x1f5] = sys_size >> 8;
  138. buf[0x1f6] = sys_size >> 16;
  139. buf[0x1f7] = sys_size >> 24;
  140. if (fwrite(buf, 1, i, stdout) != i)
  141. die("Writing setup failed");
  142. /* Copy the kernel code */
  143. if (fwrite(kernel, 1, sz, stdout) != sz)
  144. die("Writing kernel failed");
  145. close(fd);
  146. /* Everything is OK */
  147. return 0;
  148. }