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 @@ -		     THE LINUX/I386 BOOT PROTOCOL -		     ---------------------------- +		     THE LINUX/x86 BOOT PROTOCOL +		     --------------------------- -		    H. Peter Anvin <hpa@zytor.com> -			Last update 2007-05-23 - -On the i386 platform, the Linux kernel uses a rather complicated boot +On the x86 platform, the Linux kernel uses a rather complicated boot  convention.  This has evolved partially due to historical aspects, as  well as the desire in the early days to have the kernel itself be a  bootable image, the complicated PC memory model and due to changed  expectations in the PC industry caused by the effective demise of  real-mode DOS as a mainstream operating system. -Currently, the following versions of the Linux/i386 boot protocol exist. +Currently, the following versions of the Linux/x86 boot protocol exist.  Old kernels:	zImage/Image support only.  Some very early kernels  		may not even support a command line. @@ -372,10 +369,17 @@ Protocol:	2.00+  	- If 0, the protected-mode code is loaded at 0x10000.  	- If 1, the protected-mode code is loaded at 0x100000. +  Bit 5 (write): QUIET_FLAG +	- If 0, print early messages. +	- If 1, suppress early messages. +		This requests to the kernel (decompressor and early +		kernel) to not write early messages that require +		accessing the display hardware directly. +    Bit 6 (write): KEEP_SEGMENTS  	Protocol: 2.07+ -	- if 0, reload the segment registers in the 32bit entry point. -	- if 1, do not reload the segment registers in the 32bit entry point. +	- If 0, reload the segment registers in the 32bit entry point. +	- If 1, do not reload the segment registers in the 32bit entry point.  		Assume that %cs %ds %ss %es are all set to flat segments with  		a base of 0 (or the equivalent for their environment). @@ -504,7 +508,7 @@ Protocol:	2.06+    maximum size was 255.  Field name:	hardware_subarch -Type:		write +Type:		write (optional, defaults to x86/PC)  Offset/size:	0x23c/4  Protocol:	2.07+ @@ -520,11 +524,13 @@ Protocol:	2.07+    0x00000002	Xen  Field name:	hardware_subarch_data -Type:		write +Type:		write (subarch-dependent)  Offset/size:	0x240/8  Protocol:	2.07+    A pointer to data that is specific to hardware subarch +  This field is currently unused for the default x86/PC environment, +  do not modify.  Field name:	payload_offset  Type:		read @@ -545,6 +551,34 @@ Protocol:	2.08+    The length of the payload. +Field name:	setup_data +Type:		write (special) +Offset/size:	0x250/8 +Protocol:	2.09+ + +  The 64-bit physical pointer to NULL terminated single linked list of +  struct setup_data. This is used to define a more extensible boot +  parameters passing mechanism. The definition of struct setup_data is +  as follow: + +  struct setup_data { +	  u64 next; +	  u32 type; +	  u32 len; +	  u8  data[0]; +  }; + +  Where, the next is a 64-bit physical pointer to the next node of +  linked list, the next field of the last node is 0; the type is used +  to identify the contents of data; the len is the length of data +  field; the data holds the real payload. + +  This list may be modified at a number of points during the bootup +  process.  Therefore, when modifying this list one should always make +  sure to consider the case where the linked list already contains +  entries. + +  **** THE IMAGE CHECKSUM  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  file; therefore the CRC of the file up to the limit specified in the  syssize field of the header is always 0. +  **** THE KERNEL COMMAND LINE  The kernel command line has become an important way for the boot @@ -584,28 +619,6 @@ command line is entered using the following protocol:  	covered by setup_move_size, so you may need to adjust this  	field. -Field name:	setup_data -Type:		write (obligatory) -Offset/size:	0x250/8 -Protocol:	2.09+ - -  The 64-bit physical pointer to NULL terminated single linked list of -  struct setup_data. This is used to define a more extensible boot -  parameters passing mechanism. The definition of struct setup_data is -  as follow: - -  struct setup_data { -	  u64 next; -	  u32 type; -	  u32 len; -	  u8  data[0]; -  }; - -  Where, the next is a 64-bit physical pointer to the next node of -  linked list, the next field of the last node is 0; the type is used -  to identify the contents of data; the len is the length of data -  field; the data holds the real payload. -  **** MEMORY LAYOUT OF THE REAL-MODE CODE 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  	  If in doubt, say Y. +config X86_VERBOSE_BOOTUP +	bool "Enable verbose x86 bootup info messages" +	default y +	help +	  Enables the informational output from the decompression stage +	  (e.g. bzImage) of the boot. If you disable this you will still +	  see errors. Disable this if you want silent bootup. +  config EARLY_PRINTK  	bool "Early printk" if EMBEDDED  	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 @@  /* -*- linux-c -*- ------------------------------------------------------- *   *   *   Copyright (C) 1991, 1992 Linus Torvalds - *   Copyright 2007 rPath, Inc. - All Rights Reserved + *   Copyright 2007-2008 rPath, Inc. - All Rights Reserved   *   *   This file is part of the Linux kernel, and is made available under   *   the terms of the GNU General Public License version 2. @@ -95,6 +95,9 @@ static void enable_a20_kbc(void)  	outb(0xdf, 0x60);	/* A20 on */  	empty_8042(); + +	outb(0xff, 0x64);	/* Null command, but UHCI wants it */ +	empty_8042();  }  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 @@  #include <asm/io.h>  #include <asm/page.h>  #include <asm/boot.h> +#include <asm/bootparam.h>  /* WARNING!!   * This code is compiled with -fPIC and it is relocated dynamically @@ -187,13 +188,8 @@ static void gzip_release(void **);  /*   * This is set up by the setup-routine at boot-time   */ -static unsigned char *real_mode; /* Pointer to real-mode data */ - -#define RM_EXT_MEM_K   (*(unsigned short *)(real_mode + 0x2)) -#ifndef STANDARD_MEMORY_BIOS_CALL -#define RM_ALT_MEM_K   (*(unsigned long *)(real_mode + 0x1e0)) -#endif -#define RM_SCREEN_INFO (*(struct screen_info *)(real_mode+0)) +static struct boot_params *real_mode;		/* Pointer to real-mode data */ +static int quiet;  extern unsigned char input_data[];  extern int input_len; @@ -206,7 +202,8 @@ static void free(void *where);  static void *memset(void *s, int c, unsigned n);  static void *memcpy(void *dest, const void *src, unsigned n); -static void putstr(const char *); +static void __putstr(int, const char *); +#define putstr(__x)  __putstr(0, __x)  #ifdef CONFIG_X86_64  #define memptr long @@ -270,18 +267,24 @@ static void scroll(void)  		vidmem[i] = ' ';  } -static void putstr(const char *s) +static void __putstr(int error, const char *s)  {  	int x, y, pos;  	char c; +#ifndef CONFIG_X86_VERBOSE_BOOTUP +	if (!error) +		return; +#endif +  #ifdef CONFIG_X86_32 -	if (RM_SCREEN_INFO.orig_video_mode == 0 && lines == 0 && cols == 0) +	if (real_mode->screen_info.orig_video_mode == 0 && +	    lines == 0 && cols == 0)  		return;  #endif -	x = RM_SCREEN_INFO.orig_x; -	y = RM_SCREEN_INFO.orig_y; +	x = real_mode->screen_info.orig_x; +	y = real_mode->screen_info.orig_y;  	while ((c = *s++) != '\0') {  		if (c == '\n') { @@ -302,8 +305,8 @@ static void putstr(const char *s)  		}  	} -	RM_SCREEN_INFO.orig_x = x; -	RM_SCREEN_INFO.orig_y = y; +	real_mode->screen_info.orig_x = x; +	real_mode->screen_info.orig_y = y;  	pos = (x + cols * y) * 2;	/* Update cursor position */  	outb(14, vidport); @@ -366,9 +369,9 @@ static void flush_window(void)  static void error(char *x)  { -	putstr("\n\n"); -	putstr(x); -	putstr("\n\n -- System halted"); +	__putstr(1, "\n\n"); +	__putstr(1, x); +	__putstr(1, "\n\n -- System halted");  	while (1)  		asm("hlt"); @@ -395,7 +398,8 @@ static void parse_elf(void *output)  		return;  	} -	putstr("Parsing ELF... "); +	if (!quiet) +		putstr("Parsing ELF... ");  	phdrs = malloc(sizeof(*phdrs) * ehdr.e_phnum);  	if (!phdrs) @@ -430,7 +434,10 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap,  {  	real_mode = rmode; -	if (RM_SCREEN_INFO.orig_video_mode == 7) { +	if (real_mode->hdr.loadflags & QUIET_FLAG) +		quiet = 1; + +	if (real_mode->screen_info.orig_video_mode == 7) {  		vidmem = (char *) 0xb0000;  		vidport = 0x3b4;  	} else { @@ -438,8 +445,8 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap,  		vidport = 0x3d4;  	} -	lines = RM_SCREEN_INFO.orig_video_lines; -	cols = RM_SCREEN_INFO.orig_video_cols; +	lines = real_mode->screen_info.orig_video_lines; +	cols = real_mode->screen_info.orig_video_cols;  	window = output;		/* Output buffer (Normally at 1M) */  	free_mem_ptr     = heap;	/* Heap */ @@ -465,9 +472,11 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap,  #endif  	makecrc(); -	putstr("\nDecompressing Linux... "); +	if (!quiet) +		putstr("\nDecompressing Linux... ");  	gunzip();  	parse_elf(output); -	putstr("done.\nBooting the kernel.\n"); +	if (!quiet) +		putstr("done.\nBooting the kernel.\n");  	return;  } 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 @@  #define USE_BSD  #include <endian.h> -#define MAX_SHDRS 100  #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))  static Elf32_Ehdr ehdr; -static Elf32_Shdr shdr[MAX_SHDRS]; -static Elf32_Sym  *symtab[MAX_SHDRS]; -static Elf32_Rel  *reltab[MAX_SHDRS]; -static char *strtab[MAX_SHDRS];  static unsigned long reloc_count, reloc_idx;  static unsigned long *relocs; +struct section { +	Elf32_Shdr     shdr; +	struct section *link; +	Elf32_Sym      *symtab; +	Elf32_Rel      *reltab; +	char           *strtab; +}; +static struct section *secs; +  /*   * Following symbols have been audited. There values are constant and do   * 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)  {  	int i; -	for(i = 0; i < ARRAY_SIZE(safe_abs_relocs); i++) { +	for (i = 0; i < ARRAY_SIZE(safe_abs_relocs); i++) {  		if (!strcmp(sym_name, safe_abs_relocs[i]))  			/* Match found */  			return 1; @@ -137,10 +141,10 @@ static const char *sec_name(unsigned shndx)  {  	const char *sec_strtab;  	const char *name; -	sec_strtab = strtab[ehdr.e_shstrndx]; +	sec_strtab = secs[ehdr.e_shstrndx].strtab;  	name = "<noname>";  	if (shndx < ehdr.e_shnum) { -		name = sec_strtab + shdr[shndx].sh_name; +		name = sec_strtab + secs[shndx].shdr.sh_name;  	}  	else if (shndx == SHN_ABS) {  		name = "ABSOLUTE"; @@ -159,7 +163,7 @@ static const char *sym_name(const char *sym_strtab, Elf32_Sym *sym)  		name = sym_strtab + sym->st_name;  	}  	else { -		name = sec_name(shdr[sym->st_shndx].sh_name); +		name = sec_name(secs[sym->st_shndx].shdr.sh_name);  	}  	return name;  } @@ -244,29 +248,34 @@ static void read_ehdr(FILE *fp)  static void read_shdrs(FILE *fp)  {  	int i; -	if (ehdr.e_shnum > MAX_SHDRS) { -		die("%d section headers supported: %d\n", -			ehdr.e_shnum, MAX_SHDRS); +	Elf32_Shdr shdr; + +	secs = calloc(ehdr.e_shnum, sizeof(struct section)); +	if (!secs) { +		die("Unable to allocate %d section headers\n", +		    ehdr.e_shnum);  	}  	if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0) {  		die("Seek to %d failed: %s\n",  			ehdr.e_shoff, strerror(errno));  	} -	if (fread(&shdr, sizeof(shdr[0]), ehdr.e_shnum, fp) != ehdr.e_shnum) { -		die("Cannot read ELF section headers: %s\n", -			strerror(errno)); -	} -	for(i = 0; i < ehdr.e_shnum; i++) { -		shdr[i].sh_name      = elf32_to_cpu(shdr[i].sh_name); -		shdr[i].sh_type      = elf32_to_cpu(shdr[i].sh_type); -		shdr[i].sh_flags     = elf32_to_cpu(shdr[i].sh_flags); -		shdr[i].sh_addr      = elf32_to_cpu(shdr[i].sh_addr); -		shdr[i].sh_offset    = elf32_to_cpu(shdr[i].sh_offset); -		shdr[i].sh_size      = elf32_to_cpu(shdr[i].sh_size); -		shdr[i].sh_link      = elf32_to_cpu(shdr[i].sh_link); -		shdr[i].sh_info      = elf32_to_cpu(shdr[i].sh_info); -		shdr[i].sh_addralign = elf32_to_cpu(shdr[i].sh_addralign); -		shdr[i].sh_entsize   = elf32_to_cpu(shdr[i].sh_entsize); +	for (i = 0; i < ehdr.e_shnum; i++) { +		struct section *sec = &secs[i]; +		if (fread(&shdr, sizeof shdr, 1, fp) != 1) +			die("Cannot read ELF section headers %d/%d: %s\n", +			    i, ehdr.e_shnum, strerror(errno)); +		sec->shdr.sh_name      = elf32_to_cpu(shdr.sh_name); +		sec->shdr.sh_type      = elf32_to_cpu(shdr.sh_type); +		sec->shdr.sh_flags     = elf32_to_cpu(shdr.sh_flags); +		sec->shdr.sh_addr      = elf32_to_cpu(shdr.sh_addr); +		sec->shdr.sh_offset    = elf32_to_cpu(shdr.sh_offset); +		sec->shdr.sh_size      = elf32_to_cpu(shdr.sh_size); +		sec->shdr.sh_link      = elf32_to_cpu(shdr.sh_link); +		sec->shdr.sh_info      = elf32_to_cpu(shdr.sh_info); +		sec->shdr.sh_addralign = elf32_to_cpu(shdr.sh_addralign); +		sec->shdr.sh_entsize   = elf32_to_cpu(shdr.sh_entsize); +		if (sec->shdr.sh_link < ehdr.e_shnum) +			sec->link = &secs[sec->shdr.sh_link];  	}  } @@ -274,20 +283,22 @@ static void read_shdrs(FILE *fp)  static void read_strtabs(FILE *fp)  {  	int i; -	for(i = 0; i < ehdr.e_shnum; i++) { -		if (shdr[i].sh_type != SHT_STRTAB) { +	for (i = 0; i < ehdr.e_shnum; i++) { +		struct section *sec = &secs[i]; +		if (sec->shdr.sh_type != SHT_STRTAB) {  			continue;  		} -		strtab[i] = malloc(shdr[i].sh_size); -		if (!strtab[i]) { +		sec->strtab = malloc(sec->shdr.sh_size); +		if (!sec->strtab) {  			die("malloc of %d bytes for strtab failed\n", -				shdr[i].sh_size); +				sec->shdr.sh_size);  		} -		if (fseek(fp, shdr[i].sh_offset, SEEK_SET) < 0) { +		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {  			die("Seek to %d failed: %s\n", -				shdr[i].sh_offset, strerror(errno)); +				sec->shdr.sh_offset, strerror(errno));  		} -		if (fread(strtab[i], 1, shdr[i].sh_size, fp) != shdr[i].sh_size) { +		if (fread(sec->strtab, 1, sec->shdr.sh_size, fp) +		    != sec->shdr.sh_size) {  			die("Cannot read symbol table: %s\n",  				strerror(errno));  		} @@ -297,28 +308,31 @@ static void read_strtabs(FILE *fp)  static void read_symtabs(FILE *fp)  {  	int i,j; -	for(i = 0; i < ehdr.e_shnum; i++) { -		if (shdr[i].sh_type != SHT_SYMTAB) { +	for (i = 0; i < ehdr.e_shnum; i++) { +		struct section *sec = &secs[i]; +		if (sec->shdr.sh_type != SHT_SYMTAB) {  			continue;  		} -		symtab[i] = malloc(shdr[i].sh_size); -		if (!symtab[i]) { +		sec->symtab = malloc(sec->shdr.sh_size); +		if (!sec->symtab) {  			die("malloc of %d bytes for symtab failed\n", -				shdr[i].sh_size); +				sec->shdr.sh_size);  		} -		if (fseek(fp, shdr[i].sh_offset, SEEK_SET) < 0) { +		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {  			die("Seek to %d failed: %s\n", -				shdr[i].sh_offset, strerror(errno)); +				sec->shdr.sh_offset, strerror(errno));  		} -		if (fread(symtab[i], 1, shdr[i].sh_size, fp) != shdr[i].sh_size) { +		if (fread(sec->symtab, 1, sec->shdr.sh_size, fp) +		    != sec->shdr.sh_size) {  			die("Cannot read symbol table: %s\n",  				strerror(errno));  		} -		for(j = 0; j < shdr[i].sh_size/sizeof(symtab[i][0]); j++) { -			symtab[i][j].st_name  = elf32_to_cpu(symtab[i][j].st_name); -			symtab[i][j].st_value = elf32_to_cpu(symtab[i][j].st_value); -			symtab[i][j].st_size  = elf32_to_cpu(symtab[i][j].st_size); -			symtab[i][j].st_shndx = elf16_to_cpu(symtab[i][j].st_shndx); +		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Sym); j++) { +			Elf32_Sym *sym = &sec->symtab[j]; +			sym->st_name  = elf32_to_cpu(sym->st_name); +			sym->st_value = elf32_to_cpu(sym->st_value); +			sym->st_size  = elf32_to_cpu(sym->st_size); +			sym->st_shndx = elf16_to_cpu(sym->st_shndx);  		}  	}  } @@ -327,26 +341,29 @@ static void read_symtabs(FILE *fp)  static void read_relocs(FILE *fp)  {  	int i,j; -	for(i = 0; i < ehdr.e_shnum; i++) { -		if (shdr[i].sh_type != SHT_REL) { +	for (i = 0; i < ehdr.e_shnum; i++) { +		struct section *sec = &secs[i]; +		if (sec->shdr.sh_type != SHT_REL) {  			continue;  		} -		reltab[i] = malloc(shdr[i].sh_size); -		if (!reltab[i]) { +		sec->reltab = malloc(sec->shdr.sh_size); +		if (!sec->reltab) {  			die("malloc of %d bytes for relocs failed\n", -				shdr[i].sh_size); +				sec->shdr.sh_size);  		} -		if (fseek(fp, shdr[i].sh_offset, SEEK_SET) < 0) { +		if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) {  			die("Seek to %d failed: %s\n", -				shdr[i].sh_offset, strerror(errno)); +				sec->shdr.sh_offset, strerror(errno));  		} -		if (fread(reltab[i], 1, shdr[i].sh_size, fp) != shdr[i].sh_size) { +		if (fread(sec->reltab, 1, sec->shdr.sh_size, fp) +		    != sec->shdr.sh_size) {  			die("Cannot read symbol table: %s\n",  				strerror(errno));  		} -		for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) { -			reltab[i][j].r_offset = elf32_to_cpu(reltab[i][j].r_offset); -			reltab[i][j].r_info   = elf32_to_cpu(reltab[i][j].r_info); +		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) { +			Elf32_Rel *rel = &sec->reltab[j]; +			rel->r_offset = elf32_to_cpu(rel->r_offset); +			rel->r_info   = elf32_to_cpu(rel->r_info);  		}  	}  } @@ -357,19 +374,21 @@ static void print_absolute_symbols(void)  	int i;  	printf("Absolute symbols\n");  	printf(" Num:    Value Size  Type       Bind        Visibility  Name\n"); -	for(i = 0; i < ehdr.e_shnum; i++) { +	for (i = 0; i < ehdr.e_shnum; i++) { +		struct section *sec = &secs[i];  		char *sym_strtab;  		Elf32_Sym *sh_symtab;  		int j; -		if (shdr[i].sh_type != SHT_SYMTAB) { + +		if (sec->shdr.sh_type != SHT_SYMTAB) {  			continue;  		} -		sh_symtab = symtab[i]; -		sym_strtab = strtab[shdr[i].sh_link]; -		for(j = 0; j < shdr[i].sh_size/sizeof(symtab[0][0]); j++) { +		sh_symtab = sec->symtab; +		sym_strtab = sec->link->strtab; +		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Sym); j++) {  			Elf32_Sym *sym;  			const char *name; -			sym = &symtab[i][j]; +			sym = &sec->symtab[j];  			name = sym_name(sym_strtab, sym);  			if (sym->st_shndx != SHN_ABS) {  				continue; @@ -389,26 +408,27 @@ static void print_absolute_relocs(void)  {  	int i, printed = 0; -	for(i = 0; i < ehdr.e_shnum; i++) { +	for (i = 0; i < ehdr.e_shnum; i++) { +		struct section *sec = &secs[i]; +		struct section *sec_applies, *sec_symtab;  		char *sym_strtab;  		Elf32_Sym *sh_symtab; -		unsigned sec_applies, sec_symtab;  		int j; -		if (shdr[i].sh_type != SHT_REL) { +		if (sec->shdr.sh_type != SHT_REL) {  			continue;  		} -		sec_symtab  = shdr[i].sh_link; -		sec_applies = shdr[i].sh_info; -		if (!(shdr[sec_applies].sh_flags & SHF_ALLOC)) { +		sec_symtab  = sec->link; +		sec_applies = &secs[sec->shdr.sh_info]; +		if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) {  			continue;  		} -		sh_symtab = symtab[sec_symtab]; -		sym_strtab = strtab[shdr[sec_symtab].sh_link]; -		for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) { +		sh_symtab  = sec_symtab->symtab; +		sym_strtab = sec_symtab->link->strtab; +		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {  			Elf32_Rel *rel;  			Elf32_Sym *sym;  			const char *name; -			rel = &reltab[i][j]; +			rel = &sec->reltab[j];  			sym = &sh_symtab[ELF32_R_SYM(rel->r_info)];  			name = sym_name(sym_strtab, sym);  			if (sym->st_shndx != SHN_ABS) { @@ -456,26 +476,28 @@ static void walk_relocs(void (*visit)(Elf32_Rel *rel, Elf32_Sym *sym))  {  	int i;  	/* Walk through the relocations */ -	for(i = 0; i < ehdr.e_shnum; i++) { +	for (i = 0; i < ehdr.e_shnum; i++) {  		char *sym_strtab;  		Elf32_Sym *sh_symtab; -		unsigned sec_applies, sec_symtab; +		struct section *sec_applies, *sec_symtab;  		int j; -		if (shdr[i].sh_type != SHT_REL) { +		struct section *sec = &secs[i]; + +		if (sec->shdr.sh_type != SHT_REL) {  			continue;  		} -		sec_symtab  = shdr[i].sh_link; -		sec_applies = shdr[i].sh_info; -		if (!(shdr[sec_applies].sh_flags & SHF_ALLOC)) { +		sec_symtab  = sec->link; +		sec_applies = &secs[sec->shdr.sh_info]; +		if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) {  			continue;  		} -		sh_symtab = symtab[sec_symtab]; -		sym_strtab = strtab[shdr[sec_symtab].sh_link]; -		for(j = 0; j < shdr[i].sh_size/sizeof(reltab[0][0]); j++) { +		sh_symtab = sec_symtab->symtab; +		sym_strtab = sec->link->strtab; +		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {  			Elf32_Rel *rel;  			Elf32_Sym *sym;  			unsigned r_type; -			rel = &reltab[i][j]; +			rel = &sec->reltab[j];  			sym = &sh_symtab[ELF32_R_SYM(rel->r_info)];  			r_type = ELF32_R_TYPE(rel->r_info);  			/* Don't visit relocations to absolute symbols */ @@ -539,7 +561,7 @@ static void emit_relocs(int as_text)  		 */  		printf(".section \".data.reloc\",\"a\"\n");  		printf(".balign 4\n"); -		for(i = 0; i < reloc_count; i++) { +		for (i = 0; i < reloc_count; i++) {  			printf("\t .long 0x%08lx\n", relocs[i]);  		}  		printf("\n"); @@ -550,7 +572,7 @@ static void emit_relocs(int as_text)  		/* Print a stop */  		printf("%c%c%c%c", buf[0], buf[1], buf[2], buf[3]);  		/* Now print each relocation */ -		for(i = 0; i < reloc_count; i++) { +		for (i = 0; i < reloc_count; i++) {  			buf[0] = (relocs[i] >>  0) & 0xff;  			buf[1] = (relocs[i] >>  8) & 0xff;  			buf[2] = (relocs[i] >> 16) & 0xff; @@ -577,7 +599,7 @@ int main(int argc, char **argv)  	show_absolute_relocs = 0;  	as_text = 0;  	fname = NULL; -	for(i = 1; i < argc; i++) { +	for (i = 1; i < argc; i++) {  		char *arg = argv[i];  		if (*arg == '-') {  			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)  	if (level == 64) {  		return "x86-64";  	} else { +		if (level == 15) +			level = 6;  		sprintf(buf, "i%d86", level);  		return buf;  	} 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)  	/* Set the video mode */  	set_video(); +	/* Parse command line for 'quiet' and pass it to decompressor. */ +	if (cmdline_find_option_bool("quiet")) +		boot_params.hdr.loadflags |= QUIET_FLAG; +  	/* Do the last things and invoke protected mode */  	go_to_protected_mode();  } 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:  	movw	%cs, %bx  	shll	$4, %ebx  	addl	%ebx, 2f +	jmp	1f			# Short jump to serialize on 386/486 +1:  	movw	$__BOOT_DS, %cx  	movw	$__BOOT_TSS, %di @@ -40,8 +42,6 @@ protected_mode_jump:  	movl	%cr0, %edx  	orb	$X86_CR0_PE, %dl	# Protected mode  	movl	%edx, %cr0 -	jmp	1f			# Short jump to serialize on 386/486 -1:  	# Transition to 32-bit mode  	.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 {  	__u8	type_of_loader;  	__u8	loadflags;  #define LOADED_HIGH	(1<<0) +#define QUIET_FLAG	(1<<5)  #define KEEP_SEGMENTS	(1<<6)  #define CAN_USE_HEAP	(1<<7)  	__u16	setup_move_size;  | 
