diff options
| author | Ingo Molnar <mingo@elte.hu> | 2009-03-26 21:39:17 +0100 | 
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-03-27 17:28:43 +0100 | 
| commit | 6e15cf04860074ad032e88c306bea656bbdd0f22 (patch) | |
| tree | c346383bb7563e8d66b2f4a502f875b259c34870 /init | |
| parent | be0ea69674ed95e1e98cb3687a241badc756d228 (diff) | |
| parent | 60db56422043aaa455ac7f858ce23c273220f9d9 (diff) | |
| download | linux-6e15cf04860074ad032e88c306bea656bbdd0f22.tar.bz2 | |
Merge branch 'core/percpu' into percpu-cpumask-x86-for-linus-2
Conflicts:
	arch/parisc/kernel/irq.c
	arch/x86/include/asm/fixmap_64.h
	arch/x86/include/asm/setup.h
	kernel/irq/handle.c
Semantic merge:
        arch/x86/include/asm/fixmap.h
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'init')
| -rw-r--r-- | init/Kconfig | 60 | ||||
| -rw-r--r-- | init/do_mounts_rd.c | 178 | ||||
| -rw-r--r-- | init/initramfs.c | 122 | ||||
| -rw-r--r-- | init/main.c | 19 | 
4 files changed, 157 insertions, 222 deletions
diff --git a/init/Kconfig b/init/Kconfig index 68699137b147..14c483d2b7c9 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -101,6 +101,66 @@ config LOCALVERSION_AUTO  	  which is done within the script "scripts/setlocalversion".) +config HAVE_KERNEL_GZIP +	bool + +config HAVE_KERNEL_BZIP2 +	bool + +config HAVE_KERNEL_LZMA +	bool + +choice +	prompt "Kernel compression mode" +	default KERNEL_GZIP +	depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZMA +	help +	  The linux kernel is a kind of self-extracting executable. +	  Several compression algorithms are available, which differ +	  in efficiency, compression and decompression speed. +	  Compression speed is only relevant when building a kernel. +	  Decompression speed is relevant at each boot. + +	  If you have any problems with bzip2 or lzma compressed +	  kernels, mail me (Alain Knaff) <alain@knaff.lu>. (An older +	  version of this functionality (bzip2 only), for 2.4, was +	  supplied by Christian Ludwig) + +	  High compression options are mostly useful for users, who +	  are low on disk space (embedded systems), but for whom ram +	  size matters less. + +	  If in doubt, select 'gzip' + +config KERNEL_GZIP +	bool "Gzip" +	depends on HAVE_KERNEL_GZIP +	help +	  The old and tried gzip compression. Its compression ratio is +	  the poorest among the 3 choices; however its speed (both +	  compression and decompression) is the fastest. + +config KERNEL_BZIP2 +	bool "Bzip2" +	depends on HAVE_KERNEL_BZIP2 +	help +	  Its compression ratio and speed is intermediate. +	  Decompression speed is slowest among the three.  The kernel +	  size is about 10% smaller with bzip2, in comparison to gzip. +	  Bzip2 uses a large amount of memory. For modern kernels you +	  will need at least 8MB RAM or more for booting. + +config KERNEL_LZMA +	bool "LZMA" +	depends on HAVE_KERNEL_LZMA +	help +	  The most recent compression algorithm. +	  Its ratio is best, decompression speed is between the other +	  two. Compression is slowest.	The kernel size is about 33% +	  smaller with LZMA in comparison to gzip. + +endchoice +  config SWAP  	bool "Support for paging of anonymous memory (swap)"  	depends on MMU && BLOCK diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index 0f0f0cf3ba9a..027a402708de 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -11,6 +11,9 @@  #include "do_mounts.h"  #include "../fs/squashfs/squashfs_fs.h" +#include <linux/decompress/generic.h> + +  int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */  static int __init prompt_ramdisk(char *str) @@ -29,7 +32,7 @@ static int __init ramdisk_start_setup(char *str)  }  __setup("ramdisk_start=", ramdisk_start_setup); -static int __init crd_load(int in_fd, int out_fd); +static int __init crd_load(int in_fd, int out_fd, decompress_fn deco);  /*   * This routine tries to find a RAM disk image to load, and returns the @@ -38,15 +41,15 @@ static int __init crd_load(int in_fd, int out_fd);   * numbers could not be found.   *   * We currently check for the following magic numbers: - * 	minix - * 	ext2 + *	minix + *	ext2   *	romfs   *	cramfs   *	squashfs - * 	gzip + *	gzip   */ -static int __init  -identify_ramdisk_image(int fd, int start_block) +static int __init +identify_ramdisk_image(int fd, int start_block, decompress_fn *decompressor)  {  	const int size = 512;  	struct minix_super_block *minixsb; @@ -56,6 +59,7 @@ identify_ramdisk_image(int fd, int start_block)  	struct squashfs_super_block *squashfsb;  	int nblocks = -1;  	unsigned char *buf; +	const char *compress_name;  	buf = kmalloc(size, GFP_KERNEL);  	if (!buf) @@ -69,18 +73,19 @@ identify_ramdisk_image(int fd, int start_block)  	memset(buf, 0xe5, size);  	/* -	 * Read block 0 to test for gzipped kernel +	 * Read block 0 to test for compressed kernel  	 */  	sys_lseek(fd, start_block * BLOCK_SIZE, 0);  	sys_read(fd, buf, size); -	/* -	 * If it matches the gzip magic numbers, return 0 -	 */ -	if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) { -		printk(KERN_NOTICE -		       "RAMDISK: Compressed image found at block %d\n", -		       start_block); +	*decompressor = decompress_method(buf, size, &compress_name); +	if (compress_name) { +		printk(KERN_NOTICE "RAMDISK: %s image found at block %d\n", +		       compress_name, start_block); +		if (!*decompressor) +			printk(KERN_EMERG +			       "RAMDISK: %s decompressor not configured!\n", +			       compress_name);  		nblocks = 0;  		goto done;  	} @@ -142,7 +147,7 @@ identify_ramdisk_image(int fd, int start_block)  	printk(KERN_NOTICE  	       "RAMDISK: Couldn't find valid RAM disk image starting at %d.\n",  	       start_block); -	 +  done:  	sys_lseek(fd, start_block * BLOCK_SIZE, 0);  	kfree(buf); @@ -157,6 +162,7 @@ int __init rd_load_image(char *from)  	int nblocks, i, disk;  	char *buf = NULL;  	unsigned short rotate = 0; +	decompress_fn decompressor = NULL;  #if !defined(CONFIG_S390) && !defined(CONFIG_PPC_ISERIES)  	char rotator[4] = { '|' , '/' , '-' , '\\' };  #endif @@ -169,12 +175,12 @@ int __init rd_load_image(char *from)  	if (in_fd < 0)  		goto noclose_input; -	nblocks = identify_ramdisk_image(in_fd, rd_image_start); +	nblocks = identify_ramdisk_image(in_fd, rd_image_start, &decompressor);  	if (nblocks < 0)  		goto done;  	if (nblocks == 0) { -		if (crd_load(in_fd, out_fd) == 0) +		if (crd_load(in_fd, out_fd, decompressor) == 0)  			goto successful_load;  		goto done;  	} @@ -200,7 +206,7 @@ int __init rd_load_image(char *from)  		       nblocks, rd_blocks);  		goto done;  	} -		 +  	/*  	 * OK, time to copy in the data  	 */ @@ -273,138 +279,48 @@ int __init rd_load_disk(int n)  	return rd_load_image("/dev/root");  } -/* - * gzip declarations - */ - -#define OF(args)  args - -#ifndef memzero -#define memzero(s, n)     memset ((s), 0, (n)) -#endif - -typedef unsigned char  uch; -typedef unsigned short ush; -typedef unsigned long  ulg; - -#define INBUFSIZ 4096 -#define WSIZE 0x8000    /* window size--must be a power of two, and */ -			/*  at least 32K for zip's deflate method */ - -static uch *inbuf; -static uch *window; - -static unsigned insize;  /* valid bytes in inbuf */ -static unsigned inptr;   /* index of next byte to be processed in inbuf */ -static unsigned outcnt;  /* bytes in output buffer */  static int exit_code; -static int unzip_error; -static long bytes_out; +static int decompress_error;  static int crd_infd, crd_outfd; -#define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf()) -		 -/* Diagnostic functions (stubbed out) */ -#define Assert(cond,msg) -#define Trace(x) -#define Tracev(x) -#define Tracevv(x) -#define Tracec(c,x) -#define Tracecv(c,x) - -#define STATIC static -#define INIT __init - -static int  __init fill_inbuf(void); -static void __init flush_window(void); -static void __init error(char *m); - -#define NO_INFLATE_MALLOC - -#include "../lib/inflate.c" - -/* =========================================================================== - * Fill the input buffer. This is called only when the buffer is empty - * and at least one byte is really needed. - * Returning -1 does not guarantee that gunzip() will ever return. - */ -static int __init fill_inbuf(void) +static int __init compr_fill(void *buf, unsigned int len)  { -	if (exit_code) return -1; -	 -	insize = sys_read(crd_infd, inbuf, INBUFSIZ); -	if (insize == 0) { -		error("RAMDISK: ran out of compressed data"); -		return -1; -	} - -	inptr = 1; - -	return inbuf[0]; +	int r = sys_read(crd_infd, buf, len); +	if (r < 0) +		printk(KERN_ERR "RAMDISK: error while reading compressed data"); +	else if (r == 0) +		printk(KERN_ERR "RAMDISK: EOF while reading compressed data"); +	return r;  } -/* =========================================================================== - * Write the output window window[0..outcnt-1] and update crc and bytes_out. - * (Used for the decompressed data only.) - */ -static void __init flush_window(void) +static int __init compr_flush(void *window, unsigned int outcnt)  { -    ulg c = crc;         /* temporary variable */ -    unsigned n, written; -    uch *in, ch; -     -    written = sys_write(crd_outfd, window, outcnt); -    if (written != outcnt && unzip_error == 0) { -	printk(KERN_ERR "RAMDISK: incomplete write (%d != %d) %ld\n", -	       written, outcnt, bytes_out); -	unzip_error = 1; -    } -    in = window; -    for (n = 0; n < outcnt; n++) { -	    ch = *in++; -	    c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); -    } -    crc = c; -    bytes_out += (ulg)outcnt; -    outcnt = 0; +	int written = sys_write(crd_outfd, window, outcnt); +	if (written != outcnt) { +		if (decompress_error == 0) +			printk(KERN_ERR +			       "RAMDISK: incomplete write (%d != %d)\n", +			       written, outcnt); +		decompress_error = 1; +		return -1; +	} +	return outcnt;  }  static void __init error(char *x)  {  	printk(KERN_ERR "%s\n", x);  	exit_code = 1; -	unzip_error = 1; +	decompress_error = 1;  } -static int __init crd_load(int in_fd, int out_fd) +static int __init crd_load(int in_fd, int out_fd, decompress_fn deco)  {  	int result; - -	insize = 0;		/* valid bytes in inbuf */ -	inptr = 0;		/* index of next byte to be processed in inbuf */ -	outcnt = 0;		/* bytes in output buffer */ -	exit_code = 0; -	bytes_out = 0; -	crc = (ulg)0xffffffffL; /* shift register contents */ -  	crd_infd = in_fd;  	crd_outfd = out_fd; -	inbuf = kmalloc(INBUFSIZ, GFP_KERNEL); -	if (!inbuf) { -		printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n"); -		return -1; -	} -	window = kmalloc(WSIZE, GFP_KERNEL); -	if (!window) { -		printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n"); -		kfree(inbuf); -		return -1; -	} -	makecrc(); -	result = gunzip(); -	if (unzip_error) +	result = deco(NULL, 0, compr_fill, compr_flush, NULL, NULL, error); +	if (decompress_error)  		result = 1; -	kfree(inbuf); -	kfree(window);  	return result;  } diff --git a/init/initramfs.c b/init/initramfs.c index d9c941c0c3ca..7dcde7ea6603 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -390,11 +390,13 @@ static int __init write_buffer(char *buf, unsigned len)  	return len - count;  } -static void __init flush_buffer(char *buf, unsigned len) +static int __init flush_buffer(void *bufv, unsigned len)  { +	char *buf = (char *) bufv;  	int written; +	int origLen = len;  	if (message) -		return; +		return -1;  	while ((written = write_buffer(buf, len)) < len && !message) {  		char c = buf[written];  		if (c == '0') { @@ -408,84 +410,28 @@ static void __init flush_buffer(char *buf, unsigned len)  		} else  			error("junk in compressed archive");  	} +	return origLen;  } -/* - * gzip declarations - */ +static unsigned my_inptr;   /* index of next byte to be processed in inbuf */ -#define OF(args)  args - -#ifndef memzero -#define memzero(s, n)     memset ((s), 0, (n)) -#endif - -typedef unsigned char  uch; -typedef unsigned short ush; -typedef unsigned long  ulg; - -#define WSIZE 0x8000    /* window size--must be a power of two, and */ -			/*  at least 32K for zip's deflate method */ - -static uch *inbuf; -static uch *window; - -static unsigned insize;  /* valid bytes in inbuf */ -static unsigned inptr;   /* index of next byte to be processed in inbuf */ -static unsigned outcnt;  /* bytes in output buffer */ -static long bytes_out; - -#define get_byte()  (inptr < insize ? inbuf[inptr++] : -1) -		 -/* Diagnostic functions (stubbed out) */ -#define Assert(cond,msg) -#define Trace(x) -#define Tracev(x) -#define Tracevv(x) -#define Tracec(c,x) -#define Tracecv(c,x) - -#define STATIC static -#define INIT __init - -static void __init flush_window(void); -static void __init error(char *m); - -#define NO_INFLATE_MALLOC - -#include "../lib/inflate.c" - -/* =========================================================================== - * Write the output window window[0..outcnt-1] and update crc and bytes_out. - * (Used for the decompressed data only.) - */ -static void __init flush_window(void) -{ -	ulg c = crc;         /* temporary variable */ -	unsigned n; -	uch *in, ch; - -	flush_buffer(window, outcnt); -	in = window; -	for (n = 0; n < outcnt; n++) { -		ch = *in++; -		c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); -	} -	crc = c; -	bytes_out += (ulg)outcnt; -	outcnt = 0; -} +#include <linux/decompress/generic.h>  static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)  {  	int written; +	decompress_fn decompress; +	const char *compress_name; +	static __initdata char msg_buf[64]; +  	dry_run = check_only;  	header_buf = kmalloc(110, GFP_KERNEL);  	symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);  	name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL); -	window = kmalloc(WSIZE, GFP_KERNEL); -	if (!window || !header_buf || !symlink_buf || !name_buf) + +	if (!header_buf || !symlink_buf || !name_buf)  		panic("can't allocate buffers"); +  	state = Start;  	this_header = 0;  	message = NULL; @@ -505,22 +451,25 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)  			continue;  		}  		this_header = 0; -		insize = len; -		inbuf = buf; -		inptr = 0; -		outcnt = 0;		/* bytes in output buffer */ -		bytes_out = 0; -		crc = (ulg)0xffffffffL; /* shift register contents */ -		makecrc(); -		gunzip(); +		decompress = decompress_method(buf, len, &compress_name); +		if (decompress) +			decompress(buf, len, NULL, flush_buffer, NULL, +				   &my_inptr, error); +		else if (compress_name) { +			if (!message) { +				snprintf(msg_buf, sizeof msg_buf, +					 "compression method %s not configured", +					 compress_name); +				message = msg_buf; +			} +		}  		if (state != Reset) -			error("junk in gzipped archive"); -		this_header = saved_offset + inptr; -		buf += inptr; -		len -= inptr; +			error("junk in compressed archive"); +		this_header = saved_offset + my_inptr; +		buf += my_inptr; +		len -= my_inptr;  	}  	dir_utime(); -	kfree(window);  	kfree(name_buf);  	kfree(symlink_buf);  	kfree(header_buf); @@ -579,7 +528,7 @@ static int __init populate_rootfs(void)  	char *err = unpack_to_rootfs(__initramfs_start,  			 __initramfs_end - __initramfs_start, 0);  	if (err) -		panic(err); +		panic(err);	/* Failed to decompress INTERNAL initramfs */  	if (initrd_start) {  #ifdef CONFIG_BLK_DEV_RAM  		int fd; @@ -605,9 +554,12 @@ static int __init populate_rootfs(void)  		printk(KERN_INFO "Unpacking initramfs...");  		err = unpack_to_rootfs((char *)initrd_start,  			initrd_end - initrd_start, 0); -		if (err) -			panic(err); -		printk(" done\n"); +		if (err) { +			printk(" failed!\n"); +			printk(KERN_EMERG "%s\n", err); +		} else { +			printk(" done\n"); +		}  		free_initrd();  #endif  	} diff --git a/init/main.c b/init/main.c index 83697e160b3a..6bf83afd654d 100644 --- a/init/main.c +++ b/init/main.c @@ -14,6 +14,7 @@  #include <linux/proc_fs.h>  #include <linux/kernel.h>  #include <linux/syscalls.h> +#include <linux/stackprotector.h>  #include <linux/string.h>  #include <linux/ctype.h>  #include <linux/delay.h> @@ -135,14 +136,14 @@ unsigned int __initdata setup_max_cpus = NR_CPUS;   * greater than 0, limits the maximum number of CPUs activated in   * SMP mode to <NUM>.   */ -#ifndef CONFIG_X86_IO_APIC -static inline void disable_ioapic_setup(void) {}; -#endif + +void __weak arch_disable_smp_support(void) { }  static int __init nosmp(char *str)  {  	setup_max_cpus = 0; -	disable_ioapic_setup(); +	arch_disable_smp_support(); +  	return 0;  } @@ -152,14 +153,14 @@ static int __init maxcpus(char *str)  {  	get_option(&str, &setup_max_cpus);  	if (setup_max_cpus == 0) -		disable_ioapic_setup(); +		arch_disable_smp_support();  	return 0;  }  early_param("maxcpus", maxcpus);  #else -#define setup_max_cpus NR_CPUS +const unsigned int setup_max_cpus = NR_CPUS;  #endif  /* @@ -540,6 +541,12 @@ asmlinkage void __init start_kernel(void)  	 */  	lockdep_init();  	debug_objects_early_init(); + +	/* +	 * Set up the the initial canary ASAP: +	 */ +	boot_init_stack_canary(); +  	cgroup_init_early();  	local_irq_disable();  |