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