Merge branches 'x86/apic', 'x86/cpu', 'x86/fixmap', 'x86/mm', 'x86/sched', 'x86/setup-lzma', 'x86/signal' and 'x86/urgent' into x86/core

This commit is contained in:
Ingo Molnar
2009-03-04 02:22:31 +01:00
291 changed files with 5493 additions and 2777 deletions

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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
}