diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-07-08 03:43:01 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-08 03:43:01 -0400 |
commit | 3c1ca43fafea41e38cb2d0c1684119af4c1de547 (patch) | |
tree | 122e41a7b9fca26ea25ea9864180f5016274a8c8 /arch/x86/boot | |
parent | 6924d1ab8b7bbe5ab416713f5701b3316b2df85b (diff) | |
parent | 6bcb13b35a2ea39be6c7cc0292b8ad1191b1a748 (diff) |
Merge branch 'x86/setup' into x86/devel
Diffstat (limited to 'arch/x86/boot')
-rw-r--r-- | arch/x86/boot/a20.c | 5 | ||||
-rw-r--r-- | arch/x86/boot/compressed/misc.c | 55 | ||||
-rw-r--r-- | arch/x86/boot/compressed/relocs.c | 198 | ||||
-rw-r--r-- | arch/x86/boot/cpu.c | 2 | ||||
-rw-r--r-- | arch/x86/boot/main.c | 4 | ||||
-rw-r--r-- | arch/x86/boot/pmjump.S | 4 |
6 files changed, 154 insertions, 114 deletions
diff --git a/arch/x86/boot/a20.c b/arch/x86/boot/a20.c index e01aafd03bde..4063d630deff 100644 --- a/arch/x86/boot/a20.c +++ b/arch/x86/boot/a20.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* -*- linux-c -*- ------------------------------------------------------- * | 1 | /* -*- linux-c -*- ------------------------------------------------------- * |
2 | * | 2 | * |
3 | * Copyright (C) 1991, 1992 Linus Torvalds | 3 | * Copyright (C) 1991, 1992 Linus Torvalds |
4 | * Copyright 2007 rPath, Inc. - All Rights Reserved | 4 | * Copyright 2007-2008 rPath, Inc. - All Rights Reserved |
5 | * | 5 | * |
6 | * This file is part of the Linux kernel, and is made available under | 6 | * This file is part of the Linux kernel, and is made available under |
7 | * the terms of the GNU General Public License version 2. | 7 | * the terms of the GNU General Public License version 2. |
@@ -95,6 +95,9 @@ static void enable_a20_kbc(void) | |||
95 | 95 | ||
96 | outb(0xdf, 0x60); /* A20 on */ | 96 | outb(0xdf, 0x60); /* A20 on */ |
97 | empty_8042(); | 97 | empty_8042(); |
98 | |||
99 | outb(0xff, 0x64); /* Null command, but UHCI wants it */ | ||
100 | empty_8042(); | ||
98 | } | 101 | } |
99 | 102 | ||
100 | static void enable_a20_fast(void) | 103 | static void enable_a20_fast(void) |
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index 90456cee47c3..11629e903aa5 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <asm/io.h> | 30 | #include <asm/io.h> |
31 | #include <asm/page.h> | 31 | #include <asm/page.h> |
32 | #include <asm/boot.h> | 32 | #include <asm/boot.h> |
33 | #include <asm/bootparam.h> | ||
33 | 34 | ||
34 | /* WARNING!! | 35 | /* WARNING!! |
35 | * This code is compiled with -fPIC and it is relocated dynamically | 36 | * This code is compiled with -fPIC and it is relocated dynamically |
@@ -187,13 +188,8 @@ static void gzip_release(void **); | |||
187 | /* | 188 | /* |
188 | * This is set up by the setup-routine at boot-time | 189 | * This is set up by the setup-routine at boot-time |
189 | */ | 190 | */ |
190 | static unsigned char *real_mode; /* Pointer to real-mode data */ | 191 | static struct boot_params *real_mode; /* Pointer to real-mode data */ |
191 | 192 | static int quiet; | |
192 | #define RM_EXT_MEM_K (*(unsigned short *)(real_mode + 0x2)) | ||
193 | #ifndef STANDARD_MEMORY_BIOS_CALL | ||
194 | #define RM_ALT_MEM_K (*(unsigned long *)(real_mode + 0x1e0)) | ||
195 | #endif | ||
196 | #define RM_SCREEN_INFO (*(struct screen_info *)(real_mode+0)) | ||
197 | 193 | ||
198 | extern unsigned char input_data[]; | 194 | extern unsigned char input_data[]; |
199 | extern int input_len; | 195 | extern int input_len; |
@@ -206,7 +202,8 @@ static void free(void *where); | |||
206 | static void *memset(void *s, int c, unsigned n); | 202 | static void *memset(void *s, int c, unsigned n); |
207 | static void *memcpy(void *dest, const void *src, unsigned n); | 203 | static void *memcpy(void *dest, const void *src, unsigned n); |
208 | 204 | ||
209 | static void putstr(const char *); | 205 | static void __putstr(int, const char *); |
206 | #define putstr(__x) __putstr(0, __x) | ||
210 | 207 | ||
211 | #ifdef CONFIG_X86_64 | 208 | #ifdef CONFIG_X86_64 |
212 | #define memptr long | 209 | #define memptr long |
@@ -270,18 +267,24 @@ static void scroll(void) | |||
270 | vidmem[i] = ' '; | 267 | vidmem[i] = ' '; |
271 | } | 268 | } |
272 | 269 | ||
273 | static void putstr(const char *s) | 270 | static void __putstr(int error, const char *s) |
274 | { | 271 | { |
275 | int x, y, pos; | 272 | int x, y, pos; |
276 | char c; | 273 | char c; |
277 | 274 | ||
275 | #ifndef CONFIG_X86_VERBOSE_BOOTUP | ||
276 | if (!error) | ||
277 | return; | ||
278 | #endif | ||
279 | |||
278 | #ifdef CONFIG_X86_32 | 280 | #ifdef CONFIG_X86_32 |
279 | if (RM_SCREEN_INFO.orig_video_mode == 0 && lines == 0 && cols == 0) | 281 | if (real_mode->screen_info.orig_video_mode == 0 && |
282 | lines == 0 && cols == 0) | ||
280 | return; | 283 | return; |
281 | #endif | 284 | #endif |
282 | 285 | ||
283 | x = RM_SCREEN_INFO.orig_x; | 286 | x = real_mode->screen_info.orig_x; |
284 | y = RM_SCREEN_INFO.orig_y; | 287 | y = real_mode->screen_info.orig_y; |
285 | 288 | ||
286 | while ((c = *s++) != '\0') { | 289 | while ((c = *s++) != '\0') { |
287 | if (c == '\n') { | 290 | if (c == '\n') { |
@@ -302,8 +305,8 @@ static void putstr(const char *s) | |||
302 | } | 305 | } |
303 | } | 306 | } |
304 | 307 | ||
305 | RM_SCREEN_INFO.orig_x = x; | 308 | real_mode->screen_info.orig_x = x; |
306 | RM_SCREEN_INFO.orig_y = y; | 309 | real_mode->screen_info.orig_y = y; |
307 | 310 | ||
308 | pos = (x + cols * y) * 2; /* Update cursor position */ | 311 | pos = (x + cols * y) * 2; /* Update cursor position */ |
309 | outb(14, vidport); | 312 | outb(14, vidport); |
@@ -366,9 +369,9 @@ static void flush_window(void) | |||
366 | 369 | ||
367 | static void error(char *x) | 370 | static void error(char *x) |
368 | { | 371 | { |
369 | putstr("\n\n"); | 372 | __putstr(1, "\n\n"); |
370 | putstr(x); | 373 | __putstr(1, x); |
371 | putstr("\n\n -- System halted"); | 374 | __putstr(1, "\n\n -- System halted"); |
372 | 375 | ||
373 | while (1) | 376 | while (1) |
374 | asm("hlt"); | 377 | asm("hlt"); |
@@ -395,7 +398,8 @@ static void parse_elf(void *output) | |||
395 | return; | 398 | return; |
396 | } | 399 | } |
397 | 400 | ||
398 | putstr("Parsing ELF... "); | 401 | if (!quiet) |
402 | putstr("Parsing ELF... "); | ||
399 | 403 | ||
400 | phdrs = malloc(sizeof(*phdrs) * ehdr.e_phnum); | 404 | phdrs = malloc(sizeof(*phdrs) * ehdr.e_phnum); |
401 | if (!phdrs) | 405 | if (!phdrs) |
@@ -430,7 +434,10 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap, | |||
430 | { | 434 | { |
431 | real_mode = rmode; | 435 | real_mode = rmode; |
432 | 436 | ||
433 | if (RM_SCREEN_INFO.orig_video_mode == 7) { | 437 | if (real_mode->hdr.loadflags & QUIET_FLAG) |
438 | quiet = 1; | ||
439 | |||
440 | if (real_mode->screen_info.orig_video_mode == 7) { | ||
434 | vidmem = (char *) 0xb0000; | 441 | vidmem = (char *) 0xb0000; |
435 | vidport = 0x3b4; | 442 | vidport = 0x3b4; |
436 | } else { | 443 | } else { |
@@ -438,8 +445,8 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap, | |||
438 | vidport = 0x3d4; | 445 | vidport = 0x3d4; |
439 | } | 446 | } |
440 | 447 | ||
441 | lines = RM_SCREEN_INFO.orig_video_lines; | 448 | lines = real_mode->screen_info.orig_video_lines; |
442 | cols = RM_SCREEN_INFO.orig_video_cols; | 449 | cols = real_mode->screen_info.orig_video_cols; |
443 | 450 | ||
444 | window = output; /* Output buffer (Normally at 1M) */ | 451 | window = output; /* Output buffer (Normally at 1M) */ |
445 | free_mem_ptr = heap; /* Heap */ | 452 | free_mem_ptr = heap; /* Heap */ |
@@ -465,9 +472,11 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap, | |||
465 | #endif | 472 | #endif |
466 | 473 | ||
467 | makecrc(); | 474 | makecrc(); |
468 | putstr("\nDecompressing Linux... "); | 475 | if (!quiet) |
476 | putstr("\nDecompressing Linux... "); | ||
469 | gunzip(); | 477 | gunzip(); |
470 | parse_elf(output); | 478 | parse_elf(output); |
471 | putstr("done.\nBooting the kernel.\n"); | 479 | if (!quiet) |
480 | putstr("done.\nBooting the kernel.\n"); | ||
472 | return; | 481 | return; |
473 | } | 482 | } |
diff --git a/arch/x86/boot/compressed/relocs.c b/arch/x86/boot/compressed/relocs.c index edaadea90aaf..a1310c52fc0c 100644 --- a/arch/x86/boot/compressed/relocs.c +++ b/arch/x86/boot/compressed/relocs.c | |||
@@ -10,16 +10,20 @@ | |||
10 | #define USE_BSD | 10 | #define USE_BSD |
11 | #include <endian.h> | 11 | #include <endian.h> |
12 | 12 | ||
13 | #define MAX_SHDRS 100 | ||
14 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | 13 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) |
15 | static Elf32_Ehdr ehdr; | 14 | static Elf32_Ehdr ehdr; |
16 | static Elf32_Shdr shdr[MAX_SHDRS]; | ||
17 | static Elf32_Sym *symtab[MAX_SHDRS]; | ||
18 | static Elf32_Rel *reltab[MAX_SHDRS]; | ||
19 | static char *strtab[MAX_SHDRS]; | ||
20 | static unsigned long reloc_count, reloc_idx; | 15 | static unsigned long reloc_count, reloc_idx; |
21 | static unsigned long *relocs; | 16 | static unsigned long *relocs; |
22 | 17 | ||
18 | struct section { | ||
19 | Elf32_Shdr shdr; | ||
20 | struct section *link; | ||
21 | Elf32_Sym *symtab; | ||
22 | Elf32_Rel *reltab; | ||
23 | char *strtab; | ||
24 | }; | ||
25 | static struct section *secs; | ||
26 | |||
23 | /* | 27 | /* |
24 | * Following symbols have been audited. There values are constant and do | 28 | * Following symbols have been audited. There values are constant and do |
25 | * not change if bzImage is loaded at a different physical address than | 29 | * not change if bzImage is loaded at a different physical address than |
@@ -35,7 +39,7 @@ static int is_safe_abs_reloc(const char* sym_name) | |||
35 | { | 39 | { |
36 | int i; | 40 | int i; |
37 | 41 | ||
38 | for(i = 0; i < ARRAY_SIZE(safe_abs_relocs); i++) { | 42 | for (i = 0; i < ARRAY_SIZE(safe_abs_relocs); i++) { |
39 | if (!strcmp(sym_name, safe_abs_relocs[i])) | 43 | if (!strcmp(sym_name, safe_abs_relocs[i])) |
40 | /* Match found */ | 44 | /* Match found */ |
41 | return 1; | 45 | return 1; |
@@ -137,10 +141,10 @@ static const char *sec_name(unsigned shndx) | |||
137 | { | 141 | { |
138 | const char *sec_strtab; | 142 | const char *sec_strtab; |
139 | const char *name; | 143 | const char *name; |
140 | sec_strtab = strtab[ehdr.e_shstrndx]; | 144 | sec_strtab = secs[ehdr.e_shstrndx].strtab; |
141 | name = "<noname>"; | 145 | name = "<noname>"; |
142 | if (shndx < ehdr.e_shnum) { | 146 | if (shndx < ehdr.e_shnum) { |
143 | name = sec_strtab + shdr[shndx].sh_name; | 147 | name = sec_strtab + secs[shndx].shdr.sh_name; |
144 | } | 148 | } |
145 | else if (shndx == SHN_ABS) { | 149 | else if (shndx == SHN_ABS) { |
146 | name = "ABSOLUTE"; | 150 | name = "ABSOLUTE"; |
@@ -159,7 +163,7 @@ static const char *sym_name(const char *sym_strtab, Elf32_Sym *sym) | |||
159 | name = sym_strtab + sym->st_name; | 163 | name = sym_strtab + sym->st_name; |
160 | } | 164 | } |
161 | else { | 165 | else { |
162 | name = sec_name(shdr[sym->st_shndx].sh_name); | 166 | name = sec_name(secs[sym->st_shndx].shdr.sh_name); |
163 | } | 167 | } |
164 | return name; | 168 | return name; |
165 | } | 169 | } |
@@ -244,29 +248,34 @@ static void read_ehdr(FILE *fp) | |||
244 | static void read_shdrs(FILE *fp) | 248 | static void read_shdrs(FILE *fp) |
245 | { | 249 | { |
246 | int i; | 250 | int i; |
247 | if (ehdr.e_shnum > MAX_SHDRS) { | 251 | Elf32_Shdr shdr; |
248 | die("%d section headers supported: %d\n", | 252 | |
249 | ehdr.e_shnum, MAX_SHDRS); | 253 | secs = calloc(ehdr.e_shnum, sizeof(struct section)); |
254 | if (!secs) { | ||
255 | die("Unable to allocate %d section headers\n", | ||
256 | ehdr.e_shnum); | ||
250 | } | 257 | } |
251 | if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0) { | 258 | if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0) { |
252 | die("Seek to %d failed: %s\n", | 259 | die("Seek to %d failed: %s\n", |
253 | ehdr.e_shoff, strerror(errno)); | 260 | ehdr.e_shoff, strerror(errno)); |
254 | } | 261 | } |
255 | if (fread(&shdr, sizeof(shdr[0]), ehdr.e_shnum, fp) != ehdr.e_shnum) { | 262 | for (i = 0; i < ehdr.e_shnum; i++) { |
256 | die("Cannot read ELF section headers: %s\n", | 263 | struct section *sec = &secs[i]; |
257 | strerror(errno)); | 264 | if (fread(&shdr, sizeof shdr, 1, fp) != 1) |
258 | } | 265 | die("Cannot read ELF section headers %d/%d: %s\n", |
259 | for(i = 0; i < ehdr.e_shnum; i++) { | 266 | i, ehdr.e_shnum, strerror(errno)); |
260 | shdr[i].sh_name = elf32_to_cpu(shdr[i].sh_name); | 267 | sec->shdr.sh_name = elf32_to_cpu(shdr.sh_name); |
261 | shdr[i].sh_type = elf32_to_cpu(shdr[i].sh_type); | 268 | sec->shdr.sh_type = elf32_to_cpu(shdr.sh_type); |
262 | shdr[i].sh_flags = elf32_to_cpu(shdr[i].sh_flags); | 269 | sec->shdr.sh_flags = elf32_to_cpu(shdr.sh_flags); |
263 | shdr[i].sh_addr = elf32_to_cpu(shdr[i].sh_addr); | 270 | sec->shdr.sh_addr = elf32_to_cpu(shdr.sh_addr); |
264 | shdr[i].sh_offset = elf32_to_cpu(shdr[i].sh_offset); | 271 | sec->shdr.sh_offset = elf32_to_cpu(shdr.sh_offset); |
265 | shdr[i].sh_size = elf32_to_cpu(shdr[i].sh_size); | 272 | sec->shdr.sh_size = elf32_to_cpu(shdr.sh_size); |
266 | shdr[i].sh_link = elf32_to_cpu(shdr[i].sh_link); | 273 | sec->shdr.sh_link = elf32_to_cpu(shdr.sh_link); |
267 | shdr[i].sh_info = elf32_to_cpu(shdr[i].sh_info); | 274 | sec->shdr.sh_info = elf32_to_cpu(shdr.sh_info); |
268 | shdr[i].sh_addralign = elf32_to_cpu(shdr[i].sh_addralign); | 275 | sec->shdr.sh_addralign = elf32_to_cpu(shdr.sh_addralign); |
269 | shdr[i].sh_entsize = elf32_to_cpu(shdr[i].sh_entsize); | 276 | sec->shdr.sh_entsize = elf32_to_cpu(shdr.sh_entsize); |
277 | if (sec->shdr.sh_link < ehdr.e_shnum) | ||
278 | sec->link = &secs[sec->shdr.sh_link]; | ||
270 | } | 279 | } |
271 | 280 | ||
272 | } | 281 | } |
@@ -274,20 +283,22 @@ static void read_shdrs(FILE *fp) | |||
274 | static void read_strtabs(FILE *fp) | 283 | static void read_strtabs(FILE *fp) |
275 | { | 284 | { |
276 | int i; | 285 | int i; |
277 | for(i = 0; i < ehdr.e_shnum; i++) { | 286 | for (i = 0; i < ehdr.e_shnum; i++) { |
278 | if (shdr[i].sh_type != SHT_STRTAB) { | 287 | struct section *sec = &secs[i]; |
288 | if (sec->shdr.sh_type != SHT_STRTAB) { | ||
279 | continue; | 289 | continue; |
280 | } | 290 | } |
281 | strtab[i] = malloc(shdr[i].sh_size); | 291 | sec->strtab = malloc(sec->shdr.sh_size); |
282 | if (!strtab[i]) { | 292 | if (!sec->strtab) { |
283 | die("malloc of %d bytes for strtab failed\n", | 293 | die("malloc of %d bytes for strtab failed\n", |
284 | shdr[i].sh_size); | 294 | sec->shdr.sh_size); |
285 | } | 295 | } |
286 | if (fseek(fp, shdr[i].sh_offset, SEEK_SET) < 0) { | 296 | if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) { |
287 | die("Seek to %d failed: %s\n", | 297 | die("Seek to %d failed: %s\n", |
288 | shdr[i].sh_offset, strerror(errno)); | 298 | sec->shdr.sh_offset, strerror(errno)); |
289 | } | 299 | } |
290 | if (fread(strtab[i], 1, shdr[i].sh_size, fp) != shdr[i].sh_size) { | 300 | if (fread(sec->strtab, 1, sec->shdr.sh_size, fp) |
301 | != sec->shdr.sh_size) { | ||
291 | die("Cannot read symbol table: %s\n", | 302 | die("Cannot read symbol table: %s\n", |
292 | strerror(errno)); | 303 | strerror(errno)); |
293 | } | 304 | } |
@@ -297,28 +308,31 @@ static void read_strtabs(FILE *fp) | |||
297 | static void read_symtabs(FILE *fp) | 308 | static void read_symtabs(FILE *fp) |
298 | { | 309 | { |
299 | int i,j; | 310 | int i,j; |
300 | for(i = 0; i < ehdr.e_shnum; i++) { | 311 | for (i = 0; i < ehdr.e_shnum; i++) { |
301 | if (shdr[i].sh_type != SHT_SYMTAB) { | 312 | struct section *sec = &secs[i]; |
313 | if (sec->shdr.sh_type != SHT_SYMTAB) { | ||
302 | continue; | 314 | continue; |
303 | } | 315 | } |
304 | symtab[i] = malloc(shdr[i].sh_size); | 316 | sec->symtab = malloc(sec->shdr.sh_size); |
305 | if (!symtab[i]) { | 317 | if (!sec->symtab) { |
306 | die("malloc of %d bytes for symtab failed\n", | 318 | die("malloc of %d bytes for symtab failed\n", |
307 | shdr[i].sh_size); | 319 | sec->shdr.sh_size); |
308 | } | 320 | } |
309 | if (fseek(fp, shdr[i].sh_offset, SEEK_SET) < 0) { | 321 | if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) { |
310 | die("Seek to %d failed: %s\n", | 322 | die("Seek to %d failed: %s\n", |
311 | shdr[i].sh_offset, strerror(errno)); | 323 | sec->shdr.sh_offset, strerror(errno)); |
312 | } | 324 | } |
313 | if (fread(symtab[i], 1, shdr[i].sh_size, fp) != shdr[i].sh_size) { | 325 | if (fread(sec->symtab, 1, sec->shdr.sh_size, fp) |
326 | != sec->shdr.sh_size) { | ||
314 | die("Cannot read symbol table: %s\n", | 327 | die("Cannot read symbol table: %s\n", |
315 | strerror(errno)); | 328 | strerror(errno)); |
316 | } | 329 | } |
317 | for(j = 0; j < shdr[i].sh_size/sizeof(symtab[i][0]); j++) { | 330 | for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Sym); j++) { |
318 | symtab[i][j].st_name = elf32_to_cpu(symtab[i][j].st_name); | 331 | Elf32_Sym *sym = &sec->symtab[j]; |
319 | symtab[i][j].st_value = elf32_to_cpu(symtab[i][j].st_value); | 332 | sym->st_name = elf32_to_cpu(sym->st_name); |
320 | symtab[i][j].st_size = elf32_to_cpu(symtab[i][j].st_size); | 333 | sym->st_value = elf32_to_cpu(sym->st_value); |
321 | symtab[i][j].st_shndx = elf16_to_cpu(symtab[i][j].st_shndx); | 334 | sym->st_size = elf32_to_cpu(sym->st_size); |
335 | sym->st_shndx = elf16_to_cpu(sym->st_shndx); | ||
322 | } | 336 | } |
323 | } | 337 | } |
324 | } | 338 | } |
@@ -327,26 +341,29 @@ static void read_symtabs(FILE *fp) | |||
327 | static void read_relocs(FILE *fp) | 341 | static void read_relocs(FILE *fp) |
328 | { | 342 | { |
329 | int i,j; | 343 | int i,j; |
330 | for(i = 0; i < ehdr.e_shnum; i++) { | 344 | for (i = 0; i < ehdr.e_shnum; i++) { |
331 | if (shdr[i].sh_type != SHT_REL) { | 345 | struct section *sec = &secs[i]; |
346 | if (sec->shdr.sh_type != SHT_REL) { | ||
332 | continue; | 347 | continue; |
333 | } | 348 | } |
334 | reltab[i] = malloc(shdr[i].sh_size); | 349 | sec->reltab = malloc(sec->shdr.sh_size); |
335 | if (!reltab[i]) { | 350 | if (!sec->reltab) { |
336 | die("malloc of %d bytes for relocs failed\n", | 351 | die("malloc of %d bytes for relocs failed\n", |
337 | shdr[i].sh_size); | 352 | sec->shdr.sh_size); |
338 | } | 353 | } |
339 | if (fseek(fp, shdr[i].sh_offset, SEEK_SET) < 0) { | 354 | if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) { |
340 | die("Seek to %d failed: %s\n", | 355 | die("Seek to %d failed: %s\n", |
341 | shdr[i].sh_offset, strerror(errno)); | 356 | sec->shdr.sh_offset, strerror(errno)); |
342 | } | 357 | } |
343 | if (fread(reltab[i], 1, shdr[i].sh_size, fp) != shdr[i].sh_size) { | 358 | if (fread(sec->reltab, 1, sec->shdr.sh_size, fp) |
359 | != sec->shdr.sh_size) { | ||
344 | die("Cannot read symbol table: %s\n", | 360 | die("Cannot read symbol table: %s\n", |
345 | strerror(errno)); | 361 | strerror(errno)); |
346 | } | 362 | } |
347 | for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) { | 363 | for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) { |
348 | reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset); | 364 | Elf32_Rel *rel = &sec->reltab[j]; |
349 | reltab[i][j].r_info = elf32_to_cpu(reltab[i][j].r_info); | 365 | rel->r_offset = elf32_to_cpu(rel->r_offset); |
366 | rel->r_info = elf32_to_cpu(rel->r_info); | ||
350 | } | 367 | } |
351 | } | 368 | } |
352 | } | 369 | } |
@@ -357,19 +374,21 @@ static void print_absolute_symbols(void) | |||
357 | int i; | 374 | int i; |
358 | printf("Absolute symbols\n"); | 375 | printf("Absolute symbols\n"); |
359 | printf(" Num: Value Size Type Bind Visibility Name\n"); | 376 | printf(" Num: Value Size Type Bind Visibility Name\n"); |
360 | for(i = 0; i < ehdr.e_shnum; i++) { | 377 | for (i = 0; i < ehdr.e_shnum; i++) { |
378 | struct section *sec = &secs[i]; | ||
361 | char *sym_strtab; | 379 | char *sym_strtab; |
362 | Elf32_Sym *sh_symtab; | 380 | Elf32_Sym *sh_symtab; |
363 | int j; | 381 | int j; |
364 | if (shdr[i].sh_type != SHT_SYMTAB) { | 382 | |
383 | if (sec->shdr.sh_type != SHT_SYMTAB) { | ||
365 | continue; | 384 | continue; |
366 | } | 385 | } |
367 | sh_symtab = symtab[i]; | 386 | sh_symtab = sec->symtab; |
368 | sym_strtab = strtab[shdr[i].sh_link]; | 387 | sym_strtab = sec->link->strtab; |
369 | for(j = 0; j < shdr[i].sh_size/sizeof(symtab[0][0]); j++) { | 388 | for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Sym); j++) { |
370 | Elf32_Sym *sym; | 389 | Elf32_Sym *sym; |
371 | const char *name; | 390 | const char *name; |
372 | sym = &symtab[i][j]; | 391 | sym = &sec->symtab[j]; |
373 | name = sym_name(sym_strtab, sym); | 392 | name = sym_name(sym_strtab, sym); |
374 | if (sym->st_shndx != SHN_ABS) { | 393 | if (sym->st_shndx != SHN_ABS) { |
375 | continue; | 394 | continue; |
@@ -389,26 +408,27 @@ static void print_absolute_relocs(void) | |||
389 | { | 408 | { |
390 | int i, printed = 0; | 409 | int i, printed = 0; |
391 | 410 | ||
392 | for(i = 0; i < ehdr.e_shnum; i++) { | 411 | for (i = 0; i < ehdr.e_shnum; i++) { |
412 | struct section *sec = &secs[i]; | ||
413 | struct section *sec_applies, *sec_symtab; | ||
393 | char *sym_strtab; | 414 | char *sym_strtab; |
394 | Elf32_Sym *sh_symtab; | 415 | Elf32_Sym *sh_symtab; |
395 | unsigned sec_applies, sec_symtab; | ||
396 | int j; | 416 | int j; |
397 | if (shdr[i].sh_type != SHT_REL) { | 417 | if (sec->shdr.sh_type != SHT_REL) { |
398 | continue; | 418 | continue; |
399 | } | 419 | } |
400 | sec_symtab = shdr[i].sh_link; | 420 | sec_symtab = sec->link; |
401 | sec_applies = shdr[i].sh_info; | 421 | sec_applies = &secs[sec->shdr.sh_info]; |
402 | if (!(shdr[sec_applies].sh_flags & SHF_ALLOC)) { | 422 | if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) { |
403 | continue; | 423 | continue; |
404 | } | 424 | } |
405 | sh_symtab = symtab[sec_symtab]; | 425 | sh_symtab = sec_symtab->symtab; |
406 | sym_strtab = strtab[shdr[sec_symtab].sh_link]; | 426 | sym_strtab = sec_symtab->link->strtab; |
407 | for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) { | 427 | for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) { |
408 | Elf32_Rel *rel; | 428 | Elf32_Rel *rel; |
409 | Elf32_Sym *sym; | 429 | Elf32_Sym *sym; |
410 | const char *name; | 430 | const char *name; |
411 | rel = &reltab[i][j]; | 431 | rel = &sec->reltab[j]; |
412 | sym = &sh_symtab[ELF32_R_SYM(rel->r_info)]; | 432 | sym = &sh_symtab[ELF32_R_SYM(rel->r_info)]; |
413 | name = sym_name(sym_strtab, sym); | 433 | name = sym_name(sym_strtab, sym); |
414 | if (sym->st_shndx != SHN_ABS) { | 434 | if (sym->st_shndx != SHN_ABS) { |
@@ -456,26 +476,28 @@ static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym)) | |||
456 | { | 476 | { |
457 | int i; | 477 | int i; |
458 | /* Walk through the relocations */ | 478 | /* Walk through the relocations */ |
459 | for(i = 0; i < ehdr.e_shnum; i++) { | 479 | for (i = 0; i < ehdr.e_shnum; i++) { |
460 | char *sym_strtab; | 480 | char *sym_strtab; |
461 | Elf32_Sym *sh_symtab; | 481 | Elf32_Sym *sh_symtab; |
462 | unsigned sec_applies, sec_symtab; | 482 | struct section *sec_applies, *sec_symtab; |
463 | int j; | 483 | int j; |
464 | if (shdr[i].sh_type != SHT_REL) { | 484 | struct section *sec = &secs[i]; |
485 | |||
486 | if (sec->shdr.sh_type != SHT_REL) { | ||
465 | continue; | 487 | continue; |
466 | } | 488 | } |
467 | sec_symtab = shdr[i].sh_link; | 489 | sec_symtab = sec->link; |
468 | sec_applies = shdr[i].sh_info; | 490 | sec_applies = &secs[sec->shdr.sh_info]; |
469 | if (!(shdr[sec_applies].sh_flags & SHF_ALLOC)) { | 491 | if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) { |
470 | continue; | 492 | continue; |
471 | } | 493 | } |
472 | sh_symtab = symtab[sec_symtab]; | 494 | sh_symtab = sec_symtab->symtab; |
473 | sym_strtab = strtab[shdr[sec_symtab].sh_link]; | 495 | sym_strtab = sec->link->strtab; |
474 | for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) { | 496 | for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) { |
475 | Elf32_Rel *rel; | 497 | Elf32_Rel *rel; |
476 | Elf32_Sym *sym; | 498 | Elf32_Sym *sym; |
477 | unsigned r_type; | 499 | unsigned r_type; |
478 | rel = &reltab[i][j]; | 500 | rel = &sec->reltab[j]; |
479 | sym = &sh_symtab[ELF32_R_SYM(rel->r_info)]; | 501 | sym = &sh_symtab[ELF32_R_SYM(rel->r_info)]; |
480 | r_type = ELF32_R_TYPE(rel->r_info); | 502 | r_type = ELF32_R_TYPE(rel->r_info); |
481 | /* Don't visit relocations to absolute symbols */ | 503 | /* Don't visit relocations to absolute symbols */ |
@@ -539,7 +561,7 @@ static void emit_relocs(int as_text) | |||
539 | */ | 561 | */ |
540 | printf(".section \".data.reloc\",\"a\"\n"); | 562 | printf(".section \".data.reloc\",\"a\"\n"); |
541 | printf(".balign 4\n"); | 563 | printf(".balign 4\n"); |
542 | for(i = 0; i < reloc_count; i++) { | 564 | for (i = 0; i < reloc_count; i++) { |
543 | printf("\t .long 0x%08lx\n", relocs[i]); | 565 | printf("\t .long 0x%08lx\n", relocs[i]); |
544 | } | 566 | } |
545 | printf("\n"); | 567 | printf("\n"); |
@@ -550,7 +572,7 @@ static void emit_relocs(int as_text) | |||
550 | /* Print a stop */ | 572 | /* Print a stop */ |
551 | printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]); | 573 | printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]); |
552 | /* Now print each relocation */ | 574 | /* Now print each relocation */ |
553 | for(i = 0; i < reloc_count; i++) { | 575 | for (i = 0; i < reloc_count; i++) { |
554 | buf[0] = (relocs[i] >> 0) & 0xff; | 576 | buf[0] = (relocs[i] >> 0) & 0xff; |
555 | buf[1] = (relocs[i] >> 8) & 0xff; | 577 | buf[1] = (relocs[i] >> 8) & 0xff; |
556 | buf[2] = (relocs[i] >> 16) & 0xff; | 578 | buf[2] = (relocs[i] >> 16) & 0xff; |
@@ -577,7 +599,7 @@ int main(int argc, char **argv) | |||
577 | show_absolute_relocs = 0; | 599 | show_absolute_relocs = 0; |
578 | as_text = 0; | 600 | as_text = 0; |
579 | fname = NULL; | 601 | fname = NULL; |
580 | for(i = 1; i < argc; i++) { | 602 | for (i = 1; i < argc; i++) { |
581 | char *arg = argv[i]; | 603 | char *arg = argv[i]; |
582 | if (*arg == '-') { | 604 | if (*arg == '-') { |
583 | if (strcmp(argv[1], "--abs-syms") == 0) { | 605 | if (strcmp(argv[1], "--abs-syms") == 0) { |
diff --git a/arch/x86/boot/cpu.c b/arch/x86/boot/cpu.c index 00e19edd852c..92d6fd73dc7d 100644 --- a/arch/x86/boot/cpu.c +++ b/arch/x86/boot/cpu.c | |||
@@ -28,6 +28,8 @@ static char *cpu_name(int level) | |||
28 | if (level == 64) { | 28 | if (level == 64) { |
29 | return "x86-64"; | 29 | return "x86-64"; |
30 | } else { | 30 | } else { |
31 | if (level == 15) | ||
32 | level = 6; | ||
31 | sprintf(buf, "i%d86", level); | 33 | sprintf(buf, "i%d86", level); |
32 | return buf; | 34 | return buf; |
33 | } | 35 | } |
diff --git a/arch/x86/boot/main.c b/arch/x86/boot/main.c index 77569a4a3be1..2296164b54d2 100644 --- a/arch/x86/boot/main.c +++ b/arch/x86/boot/main.c | |||
@@ -165,6 +165,10 @@ void main(void) | |||
165 | /* Set the video mode */ | 165 | /* Set the video mode */ |
166 | set_video(); | 166 | set_video(); |
167 | 167 | ||
168 | /* Parse command line for 'quiet' and pass it to decompressor. */ | ||
169 | if (cmdline_find_option_bool("quiet")) | ||
170 | boot_params.hdr.loadflags |= QUIET_FLAG; | ||
171 | |||
168 | /* Do the last things and invoke protected mode */ | 172 | /* Do the last things and invoke protected mode */ |
169 | go_to_protected_mode(); | 173 | go_to_protected_mode(); |
170 | } | 174 | } |
diff --git a/arch/x86/boot/pmjump.S b/arch/x86/boot/pmjump.S index ab049d40a884..141b6e20ed31 100644 --- a/arch/x86/boot/pmjump.S +++ b/arch/x86/boot/pmjump.S | |||
@@ -33,6 +33,8 @@ protected_mode_jump: | |||
33 | movw %cs, %bx | 33 | movw %cs, %bx |
34 | shll $4, %ebx | 34 | shll $4, %ebx |
35 | addl %ebx, 2f | 35 | addl %ebx, 2f |
36 | jmp 1f # Short jump to serialize on 386/486 | ||
37 | 1: | ||
36 | 38 | ||
37 | movw $__BOOT_DS, %cx | 39 | movw $__BOOT_DS, %cx |
38 | movw $__BOOT_TSS, %di | 40 | movw $__BOOT_TSS, %di |
@@ -40,8 +42,6 @@ protected_mode_jump: | |||
40 | movl %cr0, %edx | 42 | movl %cr0, %edx |
41 | orb $X86_CR0_PE, %dl # Protected mode | 43 | orb $X86_CR0_PE, %dl # Protected mode |
42 | movl %edx, %cr0 | 44 | movl %edx, %cr0 |
43 | jmp 1f # Short jump to serialize on 386/486 | ||
44 | 1: | ||
45 | 45 | ||
46 | # Transition to 32-bit mode | 46 | # Transition to 32-bit mode |
47 | .byte 0x66, 0xea # ljmpl opcode | 47 | .byte 0x66, 0xea # ljmpl opcode |