rev |
line source |
pankso@5640
|
1 --- linux-2.6.30.4/arch/x86/mm/init.c
|
pankso@5640
|
2 +++ linux-2.6.30.4/arch/x86/mm/init.c
|
pankso@5640
|
3 @@ -381,7 +381,7 @@
|
pankso@5640
|
4 */
|
pankso@5640
|
5 set_memory_rw(begin, (end - begin) >> PAGE_SHIFT);
|
pankso@5640
|
6
|
pankso@5640
|
7 - printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
|
pankso@5640
|
8 + if (what) printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
|
pankso@5640
|
9
|
pankso@5640
|
10 for (; addr < end; addr += PAGE_SIZE) {
|
pankso@5640
|
11 ClearPageReserved(virt_to_page(addr));
|
pankso@5640
|
12
|
pankso@5640
|
13 --- linux-2.6.30.4/init/initramfs.c
|
pankso@5640
|
14 +++ linux-2.6.30.4/init/initramfs.c
|
pankso@5640
|
15 @@ -374,6 +374,52 @@
|
pankso@5640
|
16 [Reset] = do_reset,
|
pankso@5640
|
17 };
|
pankso@5640
|
18
|
pankso@5640
|
19 +#include <linux/initrd.h>
|
pankso@5640
|
20 +#define INITRD_PAGE ((PAGE_SIZE > 64*1024) ? PAGE_SIZE : 64*1024)
|
pankso@5640
|
21 +#define INITRD_DOT (1024*1024)
|
pankso@5640
|
22 +
|
pankso@5640
|
23 +static void free_rootfs_mem(unsigned long start, unsigned long end)
|
pankso@5640
|
24 +{
|
pankso@5640
|
25 + free_init_pages(NULL, start, end);
|
pankso@5640
|
26 +}
|
pankso@5640
|
27 +
|
pankso@5640
|
28 +static void _free_initrd(unsigned long initrd_start, unsigned long initrd_end,
|
pankso@5640
|
29 + void (*free_initrd_mem)(unsigned long, unsigned long));
|
pankso@5640
|
30 +
|
pankso@5640
|
31 +static struct {
|
pankso@5640
|
32 + int offset, last, inptr, freed;
|
pankso@5640
|
33 + char *max;
|
pankso@5640
|
34 +} fill;
|
pankso@5640
|
35 +
|
pankso@5640
|
36 +static void release_inbuf(unsigned n)
|
pankso@5640
|
37 +{
|
pankso@5640
|
38 + if (n >= INITRD_PAGE) {
|
pankso@5640
|
39 + unsigned rem = n % INITRD_PAGE;
|
pankso@5640
|
40 + unsigned end = initrd_start + n - rem;
|
pankso@5640
|
41 + _free_initrd(initrd_start, end, free_rootfs_mem);
|
pankso@5640
|
42 + fill.freed += n - rem;
|
pankso@5640
|
43 + if (fill.freed >= INITRD_DOT) {
|
pankso@5640
|
44 + fill.freed -= INITRD_DOT;
|
pankso@5640
|
45 + printk(".");
|
pankso@5640
|
46 + }
|
pankso@5640
|
47 + initrd_start = end;
|
pankso@5640
|
48 + fill.offset = rem;
|
pankso@5640
|
49 + }
|
pankso@5640
|
50 +}
|
pankso@5640
|
51 +
|
pankso@5640
|
52 +static int fill_buffer(void *buffer, unsigned size)
|
pankso@5640
|
53 +{
|
pankso@5640
|
54 + int max = fill.max - (char *) initrd_start - fill.offset;
|
pankso@5640
|
55 + if (max > size) max = size;
|
pankso@5640
|
56 + if (max > INITRD_PAGE) max = INITRD_PAGE;
|
pankso@5640
|
57 + memcpy(buffer, (void *)(initrd_start + fill.offset), max);
|
pankso@5640
|
58 + release_inbuf(fill.offset);
|
pankso@5640
|
59 + fill.offset += max;
|
pankso@5640
|
60 + fill.inptr += fill.last;
|
pankso@5640
|
61 + fill.last = max;
|
pankso@5640
|
62 + return max;
|
pankso@5640
|
63 +}
|
pankso@5640
|
64 +
|
pankso@5640
|
65 static int __init write_buffer(char *buf, unsigned len)
|
pankso@5640
|
66 {
|
pankso@5640
|
67 count = len;
|
pankso@5640
|
68 @@ -418,6 +463,7 @@
|
pankso@5640
|
69 decompress_fn decompress;
|
pankso@5640
|
70 const char *compress_name;
|
pankso@5640
|
71 static __initdata char msg_buf[64];
|
pankso@5640
|
72 + int early_free_initrd = (buf == (char *) initrd_start);
|
pankso@5640
|
73
|
pankso@5640
|
74 header_buf = kmalloc(110, GFP_KERNEL);
|
pankso@5640
|
75 symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
|
pankso@5640
|
76 @@ -431,11 +478,16 @@
|
pankso@5640
|
77 message = NULL;
|
pankso@5640
|
78 while (!message && len) {
|
pankso@5640
|
79 loff_t saved_offset = this_header;
|
pankso@5640
|
80 + fill.offset = buf - (char *) initrd_start;
|
pankso@5640
|
81 + fill.max = buf + len;
|
pankso@5640
|
82 + fill.inptr = fill.last = fill.freed = 0;
|
pankso@5640
|
83 if (*buf == '0' && !(this_header & 3)) {
|
pankso@5640
|
84 state = Start;
|
pankso@5640
|
85 written = write_buffer(buf, len);
|
pankso@5640
|
86 buf += written;
|
pankso@5640
|
87 len -= written;
|
pankso@5640
|
88 + if (early_free_initrd)
|
pankso@5640
|
89 + release_inbuf(buf - (char *) initrd_start);
|
pankso@5640
|
90 continue;
|
pankso@5640
|
91 }
|
pankso@5640
|
92 if (!*buf) {
|
pankso@5640
|
93 @@ -446,9 +497,15 @@
|
pankso@5640
|
94 }
|
pankso@5640
|
95 this_header = 0;
|
pankso@5640
|
96 decompress = decompress_method(buf, len, &compress_name);
|
pankso@5640
|
97 - if (decompress)
|
pankso@5640
|
98 - decompress(buf, len, NULL, flush_buffer, NULL,
|
pankso@5640
|
99 + if (decompress) {
|
pankso@5640
|
100 + if (early_free_initrd) {
|
pankso@5640
|
101 + decompress(NULL, 0, fill_buffer, flush_buffer,
|
pankso@5640
|
102 + NULL, &my_inptr, error);
|
pankso@5640
|
103 + my_inptr += fill.inptr;
|
pankso@5640
|
104 + }
|
pankso@5640
|
105 + else decompress(buf, len, NULL, flush_buffer, NULL,
|
pankso@5640
|
106 &my_inptr, error);
|
pankso@5640
|
107 + }
|
pankso@5640
|
108 else if (compress_name) {
|
pankso@5640
|
109 if (!message) {
|
pankso@5640
|
110 snprintf(msg_buf, sizeof msg_buf,
|
pankso@5640
|
111 @@ -485,7 +543,8 @@
|
pankso@5640
|
112 #include <linux/initrd.h>
|
pankso@5640
|
113 #include <linux/kexec.h>
|
pankso@5640
|
114
|
pankso@5640
|
115 -static void __init free_initrd(void)
|
pankso@5640
|
116 +static void _free_initrd(unsigned long initrd_start, unsigned long initrd_end,
|
pankso@5640
|
117 + void (*free_initrd_mem)(unsigned long, unsigned long))
|
pankso@5640
|
118 {
|
pankso@5640
|
119 #ifdef CONFIG_KEXEC
|
pankso@5640
|
120 unsigned long crashk_start = (unsigned long)__va(crashk_res.start);
|
pankso@5640
|
121 @@ -513,6 +571,12 @@
|
pankso@5640
|
122 #endif
|
pankso@5640
|
123 free_initrd_mem(initrd_start, initrd_end);
|
pankso@5640
|
124 skip:
|
pankso@5640
|
125 + ;
|
pankso@5640
|
126 +}
|
pankso@5640
|
127 +
|
pankso@5640
|
128 +static void __init free_initrd(void)
|
pankso@5640
|
129 +{
|
pankso@5640
|
130 + _free_initrd(initrd_start, initrd_end, free_initrd_mem);
|
pankso@5640
|
131 initrd_start = 0;
|
pankso@5640
|
132 initrd_end = 0;
|
pankso@5640
|
133 }
|