Merge branch 'for-3.5-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj...
[firefly-linux-kernel-4.4.55.git] / arch / x86 / boot / tools / build.c
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 */
50 u8 buf[SETUP_SECT_MAX*512];
51 int is_big_kernel;
52
53 /*----------------------------------------------------------------------*/
54
55 static const u32 crctab32[] = {
56         0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
57         0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
58         0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
59         0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
60         0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
61         0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
62         0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
63         0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
64         0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
65         0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
66         0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
67         0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
68         0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
69         0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
70         0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
71         0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
72         0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
73         0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
74         0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
75         0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
76         0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
77         0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
78         0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
79         0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
80         0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
81         0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
82         0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
83         0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
84         0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
85         0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
86         0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
87         0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
88         0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
89         0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
90         0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
91         0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
92         0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
93         0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
94         0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
95         0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
96         0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
97         0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
98         0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
99         0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
100         0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
101         0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
102         0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
103         0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
104         0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
105         0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
106         0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
107         0x2d02ef8d
108 };
109
110 static u32 partial_crc32_one(u8 c, u32 crc)
111 {
112         return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8);
113 }
114
115 static u32 partial_crc32(const u8 *s, int len, u32 crc)
116 {
117         while (len--)
118                 crc = partial_crc32_one(*s++, crc);
119         return crc;
120 }
121
122 static void die(const char * str, ...)
123 {
124         va_list args;
125         va_start(args, str);
126         vfprintf(stderr, str, args);
127         fputc('\n', stderr);
128         exit(1);
129 }
130
131 static void usage(void)
132 {
133         die("Usage: build setup system [> image]");
134 }
135
136 int main(int argc, char ** argv)
137 {
138 #ifdef CONFIG_EFI_STUB
139         unsigned int file_sz, pe_header;
140 #endif
141         unsigned int i, sz, setup_sectors;
142         int c;
143         u32 sys_size;
144         struct stat sb;
145         FILE *file;
146         int fd;
147         void *kernel;
148         u32 crc = 0xffffffffUL;
149
150         if (argc != 3)
151                 usage();
152
153         /* Copy the setup code */
154         file = fopen(argv[1], "r");
155         if (!file)
156                 die("Unable to open `%s': %m", argv[1]);
157         c = fread(buf, 1, sizeof(buf), file);
158         if (ferror(file))
159                 die("read-error on `setup'");
160         if (c < 1024)
161                 die("The setup must be at least 1024 bytes");
162         if (get_unaligned_le16(&buf[510]) != 0xAA55)
163                 die("Boot block hasn't got boot flag (0xAA55)");
164         fclose(file);
165
166         /* Pad unused space with zeros */
167         setup_sectors = (c + 511) / 512;
168         if (setup_sectors < SETUP_SECT_MIN)
169                 setup_sectors = SETUP_SECT_MIN;
170         i = setup_sectors*512;
171         memset(buf+c, 0, i-c);
172
173         /* Set the default root device */
174         put_unaligned_le16(DEFAULT_ROOT_DEV, &buf[508]);
175
176         fprintf(stderr, "Setup is %d bytes (padded to %d bytes).\n", c, i);
177
178         /* Open and stat the kernel file */
179         fd = open(argv[2], O_RDONLY);
180         if (fd < 0)
181                 die("Unable to open `%s': %m", argv[2]);
182         if (fstat(fd, &sb))
183                 die("Unable to stat `%s': %m", argv[2]);
184         sz = sb.st_size;
185         fprintf (stderr, "System is %d kB\n", (sz+1023)/1024);
186         kernel = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
187         if (kernel == MAP_FAILED)
188                 die("Unable to mmap '%s': %m", argv[2]);
189         /* Number of 16-byte paragraphs, including space for a 4-byte CRC */
190         sys_size = (sz + 15 + 4) / 16;
191
192         /* Patch the setup code with the appropriate size parameters */
193         buf[0x1f1] = setup_sectors-1;
194         put_unaligned_le32(sys_size, &buf[0x1f4]);
195
196 #ifdef CONFIG_EFI_STUB
197         file_sz = sz + i + ((sys_size * 16) - sz);
198
199         pe_header = get_unaligned_le32(&buf[0x3c]);
200
201         /* Size of image */
202         put_unaligned_le32(file_sz, &buf[pe_header + 0x50]);
203
204         /*
205          * Subtract the size of the first section (512 bytes) which
206          * includes the header and .reloc section. The remaining size
207          * is that of the .text section.
208          */
209         file_sz -= 512;
210
211         /* Size of code */
212         put_unaligned_le32(file_sz, &buf[pe_header + 0x1c]);
213
214 #ifdef CONFIG_X86_32
215         /*
216          * Address of entry point.
217          *
218          * The EFI stub entry point is +16 bytes from the start of
219          * the .text section.
220          */
221         put_unaligned_le32(i + 16, &buf[pe_header + 0x28]);
222
223         /* .text size */
224         put_unaligned_le32(file_sz, &buf[pe_header + 0xb0]);
225
226         /* .text vma */
227         put_unaligned_le32(0x200, &buf[pe_header + 0xb4]);
228
229         /* .text size of initialised data */
230         put_unaligned_le32(file_sz, &buf[pe_header + 0xb8]);
231
232         /* .text file offset */
233         put_unaligned_le32(0x200, &buf[pe_header + 0xbc]);
234 #else
235         /*
236          * Address of entry point. startup_32 is at the beginning and
237          * the 64-bit entry point (startup_64) is always 512 bytes
238          * after. The EFI stub entry point is 16 bytes after that, as
239          * the first instruction allows legacy loaders to jump over
240          * the EFI stub initialisation
241          */
242         put_unaligned_le32(i + 528, &buf[pe_header + 0x28]);
243
244         /* .text size */
245         put_unaligned_le32(file_sz, &buf[pe_header + 0xc0]);
246
247         /* .text vma */
248         put_unaligned_le32(0x200, &buf[pe_header + 0xc4]);
249
250         /* .text size of initialised data */
251         put_unaligned_le32(file_sz, &buf[pe_header + 0xc8]);
252
253         /* .text file offset */
254         put_unaligned_le32(0x200, &buf[pe_header + 0xcc]);
255 #endif /* CONFIG_X86_32 */
256 #endif /* CONFIG_EFI_STUB */
257
258         crc = partial_crc32(buf, i, crc);
259         if (fwrite(buf, 1, i, stdout) != i)
260                 die("Writing setup failed");
261
262         /* Copy the kernel code */
263         crc = partial_crc32(kernel, sz, crc);
264         if (fwrite(kernel, 1, sz, stdout) != sz)
265                 die("Writing kernel failed");
266
267         /* Add padding leaving 4 bytes for the checksum */
268         while (sz++ < (sys_size*16) - 4) {
269                 crc = partial_crc32_one('\0', crc);
270                 if (fwrite("\0", 1, 1, stdout) != 1)
271                         die("Writing padding failed");
272         }
273
274         /* Write the CRC */
275         fprintf(stderr, "CRC %x\n", crc);
276         put_unaligned_le32(crc, buf);
277         if (fwrite(buf, 1, 4, stdout) != 4)
278                 die("Writing CRC failed");
279
280         close(fd);
281
282         /* Everything is OK */
283         return 0;
284 }