aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Campbell <ijc@hellion.org.uk>2008-02-17 14:06:35 -0500
committerIngo Molnar <mingo@elte.hu>2008-04-17 11:40:46 -0400
commit7d6e737c8d2698b63ad10fd75cc6793380395d0e (patch)
tree5b5a828d807cab7dac05e1c7d80ac0262076fac6
parent099e1377269a47ed30a00ee131001988e5bcaa9c (diff)
x86: add a crc32 checksum to the kernel image.
Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--Documentation/i386/boot.txt8
-rw-r--r--arch/x86/boot/tools/build.c88
2 files changed, 95 insertions, 1 deletions
diff --git a/Documentation/i386/boot.txt b/Documentation/i386/boot.txt
index b5f5ba1ea668..05c24dfd7ecf 100644
--- a/Documentation/i386/boot.txt
+++ b/Documentation/i386/boot.txt
@@ -531,6 +531,14 @@ Protocol: 2.08+
531 531
532 The length of the compressed payload. 532 The length of the compressed payload.
533 533
534**** THE IMAGE CHECKSUM
535
536From boot protocol version 2.08 onwards the CRC-32 is calculated over
537the entire file using the characteristic polynomial 0x04C11DB7 and an
538initial remainder of 0xffffffff. The checksum is appended to the
539file; therefore the CRC of the file up to the limit specified in the
540syssize field of the header is always 0.
541
534**** THE KERNEL COMMAND LINE 542**** THE KERNEL COMMAND LINE
535 543
536The kernel command line has become an important way for the boot 544The kernel command line has become an important way for the boot
diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c
index b4248740ff0d..44dc1923c0e3 100644
--- a/arch/x86/boot/tools/build.c
+++ b/arch/x86/boot/tools/build.c
@@ -50,6 +50,75 @@ typedef unsigned long u32;
50u8 buf[SETUP_SECT_MAX*512]; 50u8 buf[SETUP_SECT_MAX*512];
51int is_big_kernel; 51int is_big_kernel;
52 52
53/*----------------------------------------------------------------------*/
54
55static 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
110static u32 partial_crc32_one(u8 c, u32 crc)
111{
112 return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8);
113}
114
115static 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
53static void die(const char * str, ...) 122static void die(const char * str, ...)
54{ 123{
55 va_list args; 124 va_list args;
@@ -74,6 +143,7 @@ int main(int argc, char ** argv)
74 FILE *file; 143 FILE *file;
75 int fd; 144 int fd;
76 void *kernel; 145 void *kernel;
146 u32 crc = 0xffffffffUL;
77 147
78 if (argc > 2 && !strcmp(argv[1], "-b")) 148 if (argc > 2 && !strcmp(argv[1], "-b"))
79 { 149 {
@@ -144,7 +214,8 @@ int main(int argc, char ** argv)
144 kernel = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0); 214 kernel = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
145 if (kernel == MAP_FAILED) 215 if (kernel == MAP_FAILED)
146 die("Unable to mmap '%s': %m", argv[2]); 216 die("Unable to mmap '%s': %m", argv[2]);
147 sys_size = (sz + 15) / 16; 217 /* Number of 16-byte paragraphs, including space for a 4-byte CRC */
218 sys_size = (sz + 15 + 4) / 16;
148 if (!is_big_kernel && sys_size > DEF_SYSSIZE) 219 if (!is_big_kernel && sys_size > DEF_SYSSIZE)
149 die("System is too big. Try using bzImage or modules."); 220 die("System is too big. Try using bzImage or modules.");
150 221
@@ -155,12 +226,27 @@ int main(int argc, char ** argv)
155 buf[0x1f6] = sys_size >> 16; 226 buf[0x1f6] = sys_size >> 16;
156 buf[0x1f7] = sys_size >> 24; 227 buf[0x1f7] = sys_size >> 24;
157 228
229 crc = partial_crc32(buf, i, crc);
158 if (fwrite(buf, 1, i, stdout) != i) 230 if (fwrite(buf, 1, i, stdout) != i)
159 die("Writing setup failed"); 231 die("Writing setup failed");
160 232
161 /* Copy the kernel code */ 233 /* Copy the kernel code */
234 crc = partial_crc32(kernel, sz, crc);
162 if (fwrite(kernel, 1, sz, stdout) != sz) 235 if (fwrite(kernel, 1, sz, stdout) != sz)
163 die("Writing kernel failed"); 236 die("Writing kernel failed");
237
238 /* Add padding leaving 4 bytes for the checksum */
239 while (sz++ < (sys_size*16) - 4) {
240 crc = partial_crc32_one('\0', crc);
241 if (fwrite("\0", 1, 1, stdout) != 1)
242 die("Writing padding failed");
243 }
244
245 /* Write the CRC */
246 fprintf(stderr, "CRC %lx\n", crc);
247 if (fwrite(&crc, 1, 4, stdout) != 4)
248 die("Writing CRC failed");
249
164 close(fd); 250 close(fd);
165 251
166 /* Everything is OK */ 252 /* Everything is OK */