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