Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
build.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1991, 1992 Linus Torvalds
3  * Copyright (C) 1997 Martin Mares
4  * Copyright (C) 2007 H. Peter Anvin
5  */
6 
7 /*
8  * This file builds a disk-image from two different files:
9  *
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 /*
19  * Changes by tytso to allow root device specification
20  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
21  * Cross compiling fixes by Gertjan van Wingerde, July 1996
22  * Rewritten by Martin Mares, April 1997
23  * Substantially overhauled by H. Peter Anvin, April 2007
24  */
25 
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <stdarg.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <unistd.h>
33 #include <fcntl.h>
34 #include <sys/mman.h>
35 #include <tools/le_byteshift.h>
36 
37 typedef unsigned char u8;
38 typedef unsigned short u16;
39 typedef unsigned int u32;
40 
41 #define DEFAULT_MAJOR_ROOT 0
42 #define DEFAULT_MINOR_ROOT 0
43 #define DEFAULT_ROOT_DEV (DEFAULT_MAJOR_ROOT << 8 | DEFAULT_MINOR_ROOT)
44 
45 /* Minimal number of setup sectors */
46 #define SETUP_SECT_MIN 5
47 #define SETUP_SECT_MAX 64
48 
49 /* This must be large enough to hold the entire setup */
52 
53 #define PECOFF_RELOC_RESERVE 0x20
54 
55 /*----------------------------------------------------------------------*/
56 
57 static const u32 crctab32[] = {
58  0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
59  0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
60  0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
61  0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
62  0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
63  0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
64  0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
65  0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
66  0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
67  0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
68  0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
69  0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
70  0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
71  0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
72  0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
73  0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
74  0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
75  0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
76  0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
77  0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
78  0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
79  0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
80  0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
81  0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
82  0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
83  0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
84  0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
85  0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
86  0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
87  0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
88  0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
89  0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
90  0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
91  0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
92  0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
93  0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
94  0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
95  0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
96  0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
97  0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
98  0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
99  0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
100  0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
101  0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
102  0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
103  0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
104  0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
105  0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
106  0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
107  0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
108  0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
109  0x2d02ef8d
110 };
111 
112 static u32 partial_crc32_one(u8 c, u32 crc)
113 {
114  return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8);
115 }
116 
117 static u32 partial_crc32(const u8 *s, int len, u32 crc)
118 {
119  while (len--)
120  crc = partial_crc32_one(*s++, crc);
121  return crc;
122 }
123 
124 static void die(const char * str, ...)
125 {
126  va_list args;
127  va_start(args, str);
128  vfprintf(stderr, str, args);
129  fputc('\n', stderr);
130  exit(1);
131 }
132 
133 static void usage(void)
134 {
135  die("Usage: build setup system [> image]");
136 }
137 
138 #ifdef CONFIG_EFI_STUB
139 
140 static void update_pecoff_section_header(char *section_name, u32 offset, u32 size)
141 {
142  unsigned int pe_header;
143  unsigned short num_sections;
144  u8 *section;
145 
146  pe_header = get_unaligned_le32(&buf[0x3c]);
147  num_sections = get_unaligned_le16(&buf[pe_header + 6]);
148 
149 #ifdef CONFIG_X86_32
150  section = &buf[pe_header + 0xa8];
151 #else
152  section = &buf[pe_header + 0xb8];
153 #endif
154 
155  while (num_sections > 0) {
156  if (strncmp((char*)section, section_name, 8) == 0) {
157  /* section header size field */
158  put_unaligned_le32(size, section + 0x8);
159 
160  /* section header vma field */
161  put_unaligned_le32(offset, section + 0xc);
162 
163  /* section header 'size of initialised data' field */
164  put_unaligned_le32(size, section + 0x10);
165 
166  /* section header 'file offset' field */
167  put_unaligned_le32(offset, section + 0x14);
168 
169  break;
170  }
171  section += 0x28;
172  num_sections--;
173  }
174 }
175 
176 static void update_pecoff_setup_and_reloc(unsigned int size)
177 {
178  u32 setup_offset = 0x200;
180  u32 setup_size = reloc_offset - setup_offset;
181 
182  update_pecoff_section_header(".setup", setup_offset, setup_size);
183  update_pecoff_section_header(".reloc", reloc_offset, PECOFF_RELOC_RESERVE);
184 
185  /*
186  * Modify .reloc section contents with a single entry. The
187  * relocation is applied to offset 10 of the relocation section.
188  */
189  put_unaligned_le32(reloc_offset + 10, &buf[reloc_offset]);
190  put_unaligned_le32(10, &buf[reloc_offset + 4]);
191 }
192 
193 static void update_pecoff_text(unsigned int text_start, unsigned int file_sz)
194 {
195  unsigned int pe_header;
196  unsigned int text_sz = file_sz - text_start;
197 
198  pe_header = get_unaligned_le32(&buf[0x3c]);
199 
200  /* Size of image */
201  put_unaligned_le32(file_sz, &buf[pe_header + 0x50]);
202 
203  /*
204  * Size of code: Subtract the size of the first sector (512 bytes)
205  * which includes the header.
206  */
207  put_unaligned_le32(file_sz - 512, &buf[pe_header + 0x1c]);
208 
209 #ifdef CONFIG_X86_32
210  /*
211  * Address of entry point.
212  *
213  * The EFI stub entry point is +16 bytes from the start of
214  * the .text section.
215  */
216  put_unaligned_le32(text_start + 16, &buf[pe_header + 0x28]);
217 #else
218  /*
219  * Address of entry point. startup_32 is at the beginning and
220  * the 64-bit entry point (startup_64) is always 512 bytes
221  * after. The EFI stub entry point is 16 bytes after that, as
222  * the first instruction allows legacy loaders to jump over
223  * the EFI stub initialisation
224  */
225  put_unaligned_le32(text_start + 528, &buf[pe_header + 0x28]);
226 #endif /* CONFIG_X86_32 */
227 
228  update_pecoff_section_header(".text", text_start, text_sz);
229 }
230 
231 #endif /* CONFIG_EFI_STUB */
232 
233 int main(int argc, char ** argv)
234 {
235  unsigned int i, sz, setup_sectors;
236  int c;
237  u32 sys_size;
238  struct stat sb;
239  FILE *file;
240  int fd;
241  void *kernel;
242  u32 crc = 0xffffffffUL;
243 
244  if (argc != 3)
245  usage();
246 
247  /* Copy the setup code */
248  file = fopen(argv[1], "r");
249  if (!file)
250  die("Unable to open `%s': %m", argv[1]);
251  c = fread(buf, 1, sizeof(buf), file);
252  if (ferror(file))
253  die("read-error on `setup'");
254  if (c < 1024)
255  die("The setup must be at least 1024 bytes");
256  if (get_unaligned_le16(&buf[510]) != 0xAA55)
257  die("Boot block hasn't got boot flag (0xAA55)");
258  fclose(file);
259 
260 #ifdef CONFIG_EFI_STUB
261  /* Reserve 0x20 bytes for .reloc section */
264 #endif
265 
266  /* Pad unused space with zeros */
267  setup_sectors = (c + 511) / 512;
268  if (setup_sectors < SETUP_SECT_MIN)
269  setup_sectors = SETUP_SECT_MIN;
270  i = setup_sectors*512;
271  memset(buf+c, 0, i-c);
272 
273 #ifdef CONFIG_EFI_STUB
274  update_pecoff_setup_and_reloc(i);
275 #endif
276 
277  /* Set the default root device */
278  put_unaligned_le16(DEFAULT_ROOT_DEV, &buf[508]);
279 
280  fprintf(stderr, "Setup is %d bytes (padded to %d bytes).\n", c, i);
281 
282  /* Open and stat the kernel file */
283  fd = open(argv[2], O_RDONLY);
284  if (fd < 0)
285  die("Unable to open `%s': %m", argv[2]);
286  if (fstat(fd, &sb))
287  die("Unable to stat `%s': %m", argv[2]);
288  sz = sb.st_size;
289  fprintf (stderr, "System is %d kB\n", (sz+1023)/1024);
290  kernel = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
291  if (kernel == MAP_FAILED)
292  die("Unable to mmap '%s': %m", argv[2]);
293  /* Number of 16-byte paragraphs, including space for a 4-byte CRC */
294  sys_size = (sz + 15 + 4) / 16;
295 
296  /* Patch the setup code with the appropriate size parameters */
297  buf[0x1f1] = setup_sectors-1;
298  put_unaligned_le32(sys_size, &buf[0x1f4]);
299 
300 #ifdef CONFIG_EFI_STUB
301  update_pecoff_text(setup_sectors * 512, sz + i + ((sys_size * 16) - sz));
302 #endif
303 
304  crc = partial_crc32(buf, i, crc);
305  if (fwrite(buf, 1, i, stdout) != i)
306  die("Writing setup failed");
307 
308  /* Copy the kernel code */
309  crc = partial_crc32(kernel, sz, crc);
310  if (fwrite(kernel, 1, sz, stdout) != sz)
311  die("Writing kernel failed");
312 
313  /* Add padding leaving 4 bytes for the checksum */
314  while (sz++ < (sys_size*16) - 4) {
315  crc = partial_crc32_one('\0', crc);
316  if (fwrite("\0", 1, 1, stdout) != 1)
317  die("Writing padding failed");
318  }
319 
320  /* Write the CRC */
321  fprintf(stderr, "CRC %x\n", crc);
322  put_unaligned_le32(crc, buf);
323  if (fwrite(buf, 1, 4, stdout) != 4)
324  die("Writing CRC failed");
325 
326  close(fd);
327 
328  /* Everything is OK */
329  return 0;
330 }