diff options
-rw-r--r-- | Documentation/x86/i386/IO-APIC.txt (renamed from Documentation/i386/IO-APIC.txt) | 0 | ||||
-rw-r--r-- | Documentation/x86/i386/boot.txt (renamed from Documentation/i386/boot.txt) | 79 | ||||
-rw-r--r-- | Documentation/x86/i386/usb-legacy-support.txt (renamed from Documentation/i386/usb-legacy-support.txt) | 0 | ||||
-rw-r--r-- | Documentation/x86/i386/zero-page.txt (renamed from Documentation/i386/zero-page.txt) | 0 | ||||
-rw-r--r-- | Documentation/x86/x86_64/00-INDEX (renamed from Documentation/x86_64/00-INDEX) | 0 | ||||
-rw-r--r-- | Documentation/x86/x86_64/boot-options.txt (renamed from Documentation/x86_64/boot-options.txt) | 0 | ||||
-rw-r--r-- | Documentation/x86/x86_64/cpu-hotplug-spec (renamed from Documentation/x86_64/cpu-hotplug-spec) | 0 | ||||
-rw-r--r-- | Documentation/x86/x86_64/fake-numa-for-cpusets (renamed from Documentation/x86_64/fake-numa-for-cpusets) | 0 | ||||
-rw-r--r-- | Documentation/x86/x86_64/kernel-stacks (renamed from Documentation/x86_64/kernel-stacks) | 0 | ||||
-rw-r--r-- | Documentation/x86/x86_64/machinecheck (renamed from Documentation/x86_64/machinecheck) | 0 | ||||
-rw-r--r-- | Documentation/x86/x86_64/mm.txt (renamed from Documentation/x86_64/mm.txt) | 0 | ||||
-rw-r--r-- | Documentation/x86/x86_64/uefi.txt (renamed from Documentation/x86_64/uefi.txt) | 0 | ||||
-rw-r--r-- | arch/x86/Kconfig.debug | 8 | ||||
-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 | ||||
-rw-r--r-- | include/asm-x86/bootparam.h | 1 |
20 files changed, 209 insertions, 147 deletions
diff --git a/Documentation/i386/IO-APIC.txt b/Documentation/x86/i386/IO-APIC.txt index 30b4c714fbe1..30b4c714fbe1 100644 --- a/Documentation/i386/IO-APIC.txt +++ b/Documentation/x86/i386/IO-APIC.txt | |||
diff --git a/Documentation/i386/boot.txt b/Documentation/x86/i386/boot.txt index 95ad15c3b01f..147bfe511cdd 100644 --- a/Documentation/i386/boot.txt +++ b/Documentation/x86/i386/boot.txt | |||
@@ -1,17 +1,14 @@ | |||
1 | THE LINUX/I386 BOOT PROTOCOL | 1 | THE LINUX/x86 BOOT PROTOCOL |
2 | ---------------------------- | 2 | --------------------------- |
3 | 3 | ||
4 | H. Peter Anvin <hpa@zytor.com> | 4 | On the x86 platform, the Linux kernel uses a rather complicated boot |
5 | Last update 2007-05-23 | ||
6 | |||
7 | On the i386 platform, the Linux kernel uses a rather complicated boot | ||
8 | convention. This has evolved partially due to historical aspects, as | 5 | convention. This has evolved partially due to historical aspects, as |
9 | well as the desire in the early days to have the kernel itself be a | 6 | well as the desire in the early days to have the kernel itself be a |
10 | bootable image, the complicated PC memory model and due to changed | 7 | bootable image, the complicated PC memory model and due to changed |
11 | expectations in the PC industry caused by the effective demise of | 8 | expectations in the PC industry caused by the effective demise of |
12 | real-mode DOS as a mainstream operating system. | 9 | real-mode DOS as a mainstream operating system. |
13 | 10 | ||
14 | Currently, the following versions of the Linux/i386 boot protocol exist. | 11 | Currently, the following versions of the Linux/x86 boot protocol exist. |
15 | 12 | ||
16 | Old kernels: zImage/Image support only. Some very early kernels | 13 | Old kernels: zImage/Image support only. Some very early kernels |
17 | may not even support a command line. | 14 | may not even support a command line. |
@@ -372,10 +369,17 @@ Protocol: 2.00+ | |||
372 | - If 0, the protected-mode code is loaded at 0x10000. | 369 | - If 0, the protected-mode code is loaded at 0x10000. |
373 | - If 1, the protected-mode code is loaded at 0x100000. | 370 | - If 1, the protected-mode code is loaded at 0x100000. |
374 | 371 | ||
372 | Bit 5 (write): QUIET_FLAG | ||
373 | - If 0, print early messages. | ||
374 | - If 1, suppress early messages. | ||
375 | This requests to the kernel (decompressor and early | ||
376 | kernel) to not write early messages that require | ||
377 | accessing the display hardware directly. | ||
378 | |||
375 | Bit 6 (write): KEEP_SEGMENTS | 379 | Bit 6 (write): KEEP_SEGMENTS |
376 | Protocol: 2.07+ | 380 | Protocol: 2.07+ |
377 | - if 0, reload the segment registers in the 32bit entry point. | 381 | - If 0, reload the segment registers in the 32bit entry point. |
378 | - if 1, do not reload the segment registers in the 32bit entry point. | 382 | - If 1, do not reload the segment registers in the 32bit entry point. |
379 | Assume that %cs %ds %ss %es are all set to flat segments with | 383 | Assume that %cs %ds %ss %es are all set to flat segments with |
380 | a base of 0 (or the equivalent for their environment). | 384 | a base of 0 (or the equivalent for their environment). |
381 | 385 | ||
@@ -504,7 +508,7 @@ Protocol: 2.06+ | |||
504 | maximum size was 255. | 508 | maximum size was 255. |
505 | 509 | ||
506 | Field name: hardware_subarch | 510 | Field name: hardware_subarch |
507 | Type: write | 511 | Type: write (optional, defaults to x86/PC) |
508 | Offset/size: 0x23c/4 | 512 | Offset/size: 0x23c/4 |
509 | Protocol: 2.07+ | 513 | Protocol: 2.07+ |
510 | 514 | ||
@@ -520,11 +524,13 @@ Protocol: 2.07+ | |||
520 | 0x00000002 Xen | 524 | 0x00000002 Xen |
521 | 525 | ||
522 | Field name: hardware_subarch_data | 526 | Field name: hardware_subarch_data |
523 | Type: write | 527 | Type: write (subarch-dependent) |
524 | Offset/size: 0x240/8 | 528 | Offset/size: 0x240/8 |
525 | Protocol: 2.07+ | 529 | Protocol: 2.07+ |
526 | 530 | ||
527 | A pointer to data that is specific to hardware subarch | 531 | A pointer to data that is specific to hardware subarch |
532 | This field is currently unused for the default x86/PC environment, | ||
533 | do not modify. | ||
528 | 534 | ||
529 | Field name: payload_offset | 535 | Field name: payload_offset |
530 | Type: read | 536 | Type: read |
@@ -545,6 +551,34 @@ Protocol: 2.08+ | |||
545 | 551 | ||
546 | The length of the payload. | 552 | The length of the payload. |
547 | 553 | ||
554 | Field name: setup_data | ||
555 | Type: write (special) | ||
556 | Offset/size: 0x250/8 | ||
557 | Protocol: 2.09+ | ||
558 | |||
559 | The 64-bit physical pointer to NULL terminated single linked list of | ||
560 | struct setup_data. This is used to define a more extensible boot | ||
561 | parameters passing mechanism. The definition of struct setup_data is | ||
562 | as follow: | ||
563 | |||
564 | struct setup_data { | ||
565 | u64 next; | ||
566 | u32 type; | ||
567 | u32 len; | ||
568 | u8 data[0]; | ||
569 | }; | ||
570 | |||
571 | Where, the next is a 64-bit physical pointer to the next node of | ||
572 | linked list, the next field of the last node is 0; the type is used | ||
573 | to identify the contents of data; the len is the length of data | ||
574 | field; the data holds the real payload. | ||
575 | |||
576 | This list may be modified at a number of points during the bootup | ||
577 | process. Therefore, when modifying this list one should always make | ||
578 | sure to consider the case where the linked list already contains | ||
579 | entries. | ||
580 | |||
581 | |||
548 | **** THE IMAGE CHECKSUM | 582 | **** THE IMAGE CHECKSUM |
549 | 583 | ||
550 | From boot protocol version 2.08 onwards the CRC-32 is calculated over | 584 | From boot protocol version 2.08 onwards the CRC-32 is calculated over |
@@ -553,6 +587,7 @@ initial remainder of 0xffffffff. The checksum is appended to the | |||
553 | file; therefore the CRC of the file up to the limit specified in the | 587 | file; therefore the CRC of the file up to the limit specified in the |
554 | syssize field of the header is always 0. | 588 | syssize field of the header is always 0. |
555 | 589 | ||
590 | |||
556 | **** THE KERNEL COMMAND LINE | 591 | **** THE KERNEL COMMAND LINE |
557 | 592 | ||
558 | The kernel command line has become an important way for the boot | 593 | The kernel command line has become an important way for the boot |
@@ -584,28 +619,6 @@ command line is entered using the following protocol: | |||
584 | covered by setup_move_size, so you may need to adjust this | 619 | covered by setup_move_size, so you may need to adjust this |
585 | field. | 620 | field. |
586 | 621 | ||
587 | Field name: setup_data | ||
588 | Type: write (obligatory) | ||
589 | Offset/size: 0x250/8 | ||
590 | Protocol: 2.09+ | ||
591 | |||
592 | The 64-bit physical pointer to NULL terminated single linked list of | ||
593 | struct setup_data. This is used to define a more extensible boot | ||
594 | parameters passing mechanism. The definition of struct setup_data is | ||
595 | as follow: | ||
596 | |||
597 | struct setup_data { | ||
598 | u64 next; | ||
599 | u32 type; | ||
600 | u32 len; | ||
601 | u8 data[0]; | ||
602 | }; | ||
603 | |||
604 | Where, the next is a 64-bit physical pointer to the next node of | ||
605 | linked list, the next field of the last node is 0; the type is used | ||
606 | to identify the contents of data; the len is the length of data | ||
607 | field; the data holds the real payload. | ||
608 | |||
609 | 622 | ||
610 | **** MEMORY LAYOUT OF THE REAL-MODE CODE | 623 | **** MEMORY LAYOUT OF THE REAL-MODE CODE |
611 | 624 | ||
diff --git a/Documentation/i386/usb-legacy-support.txt b/Documentation/x86/i386/usb-legacy-support.txt index 1894cdfc69d9..1894cdfc69d9 100644 --- a/Documentation/i386/usb-legacy-support.txt +++ b/Documentation/x86/i386/usb-legacy-support.txt | |||
diff --git a/Documentation/i386/zero-page.txt b/Documentation/x86/i386/zero-page.txt index 169ad423a3d1..169ad423a3d1 100644 --- a/Documentation/i386/zero-page.txt +++ b/Documentation/x86/i386/zero-page.txt | |||
diff --git a/Documentation/x86_64/00-INDEX b/Documentation/x86/x86_64/00-INDEX index 92fc20ab5f0e..92fc20ab5f0e 100644 --- a/Documentation/x86_64/00-INDEX +++ b/Documentation/x86/x86_64/00-INDEX | |||
diff --git a/Documentation/x86_64/boot-options.txt b/Documentation/x86/x86_64/boot-options.txt index b0c7b6c4abda..b0c7b6c4abda 100644 --- a/Documentation/x86_64/boot-options.txt +++ b/Documentation/x86/x86_64/boot-options.txt | |||
diff --git a/Documentation/x86_64/cpu-hotplug-spec b/Documentation/x86/x86_64/cpu-hotplug-spec index 3c23e0587db3..3c23e0587db3 100644 --- a/Documentation/x86_64/cpu-hotplug-spec +++ b/Documentation/x86/x86_64/cpu-hotplug-spec | |||
diff --git a/Documentation/x86_64/fake-numa-for-cpusets b/Documentation/x86/x86_64/fake-numa-for-cpusets index d1a985c5b00a..d1a985c5b00a 100644 --- a/Documentation/x86_64/fake-numa-for-cpusets +++ b/Documentation/x86/x86_64/fake-numa-for-cpusets | |||
diff --git a/Documentation/x86_64/kernel-stacks b/Documentation/x86/x86_64/kernel-stacks index 5ad65d51fb95..5ad65d51fb95 100644 --- a/Documentation/x86_64/kernel-stacks +++ b/Documentation/x86/x86_64/kernel-stacks | |||
diff --git a/Documentation/x86_64/machinecheck b/Documentation/x86/x86_64/machinecheck index a05e58e7b159..a05e58e7b159 100644 --- a/Documentation/x86_64/machinecheck +++ b/Documentation/x86/x86_64/machinecheck | |||
diff --git a/Documentation/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt index efce75097369..efce75097369 100644 --- a/Documentation/x86_64/mm.txt +++ b/Documentation/x86/x86_64/mm.txt | |||
diff --git a/Documentation/x86_64/uefi.txt b/Documentation/x86/x86_64/uefi.txt index 7d77120a5184..7d77120a5184 100644 --- a/Documentation/x86_64/uefi.txt +++ b/Documentation/x86/x86_64/uefi.txt | |||
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 18363374d51a..38a15333f725 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug | |||
@@ -20,6 +20,14 @@ config NONPROMISC_DEVMEM | |||
20 | 20 | ||
21 | If in doubt, say Y. | 21 | If in doubt, say Y. |
22 | 22 | ||
23 | config X86_VERBOSE_BOOTUP | ||
24 | bool "Enable verbose x86 bootup info messages" | ||
25 | default y | ||
26 | help | ||
27 | Enables the informational output from the decompression stage | ||
28 | (e.g. bzImage) of the boot. If you disable this you will still | ||
29 | see errors. Disable this if you want silent bootup. | ||
30 | |||
23 | config EARLY_PRINTK | 31 | config EARLY_PRINTK |
24 | bool "Early printk" if EMBEDDED | 32 | bool "Early printk" if EMBEDDED |
25 | default y | 33 | default y |
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 |
diff --git a/include/asm-x86/bootparam.h b/include/asm-x86/bootparam.h index f62f4733606b..3e36ba8f288b 100644 --- a/include/asm-x86/bootparam.h +++ b/include/asm-x86/bootparam.h | |||
@@ -40,6 +40,7 @@ struct setup_header { | |||
40 | __u8 type_of_loader; | 40 | __u8 type_of_loader; |
41 | __u8 loadflags; | 41 | __u8 loadflags; |
42 | #define LOADED_HIGH (1<<0) | 42 | #define LOADED_HIGH (1<<0) |
43 | #define QUIET_FLAG (1<<5) | ||
43 | #define KEEP_SEGMENTS (1<<6) | 44 | #define KEEP_SEGMENTS (1<<6) |
44 | #define CAN_USE_HEAP (1<<7) | 45 | #define CAN_USE_HEAP (1<<7) |
45 | __u16 setup_move_size; | 46 | __u16 setup_move_size; |