diff options
author | Michal Simek <monstr@monstr.eu> | 2009-05-19 08:33:47 -0400 |
---|---|---|
committer | Michal Simek <monstr@monstr.eu> | 2009-05-21 10:39:16 -0400 |
commit | cda1fd5a60e97a1a1bf96606f201818b207b2c5c (patch) | |
tree | 33bc265a4182985778f80a0efc25f0a26fd0aa7e | |
parent | 1dff89a9c7fab71b43ba79cc1aa6c6dbad582a35 (diff) |
microblaze: Cleanup compiled-in rootfs in BSS section
This patch is based on patch from Steve Magnani.
There were bug for compiled-in rootfs. We have to move
moving rootfs which is in BSS section to _ebss section
which is at the end of kernel and then clear bss section
not vice-versa.
Signed-off-by: Michal Simek <monstr@monstr.eu>
-rw-r--r-- | arch/microblaze/kernel/setup.c | 53 |
1 files changed, 32 insertions, 21 deletions
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c index c156b16f9ee9..8709bea09604 100644 --- a/arch/microblaze/kernel/setup.c +++ b/arch/microblaze/kernel/setup.c | |||
@@ -98,6 +98,29 @@ void __init machine_early_init(const char *cmdline, unsigned int ram, | |||
98 | { | 98 | { |
99 | unsigned long *src, *dst = (unsigned long *)0x0; | 99 | unsigned long *src, *dst = (unsigned long *)0x0; |
100 | 100 | ||
101 | /* If CONFIG_MTD_UCLINUX is defined, assume ROMFS is at the | ||
102 | * end of kernel. There are two position which we want to check. | ||
103 | * The first is __init_end and the second __bss_start. | ||
104 | */ | ||
105 | #ifdef CONFIG_MTD_UCLINUX | ||
106 | int romfs_size; | ||
107 | unsigned int romfs_base; | ||
108 | char *old_klimit = klimit; | ||
109 | |||
110 | romfs_base = (ram ? ram : (unsigned int)&__init_end); | ||
111 | romfs_size = PAGE_ALIGN(get_romfs_len((unsigned *)romfs_base)); | ||
112 | if (!romfs_size) { | ||
113 | romfs_base = (unsigned int)&__bss_start; | ||
114 | romfs_size = PAGE_ALIGN(get_romfs_len((unsigned *)romfs_base)); | ||
115 | } | ||
116 | |||
117 | /* Move ROMFS out of BSS before clearing it */ | ||
118 | if (romfs_size > 0) { | ||
119 | memmove(&_ebss, (int *)romfs_base, romfs_size); | ||
120 | klimit += romfs_size; | ||
121 | } | ||
122 | #endif | ||
123 | |||
101 | /* clearing bss section */ | 124 | /* clearing bss section */ |
102 | memset(__bss_start, 0, __bss_stop-__bss_start); | 125 | memset(__bss_start, 0, __bss_stop-__bss_start); |
103 | memset(_ssbss, 0, _esbss-_ssbss); | 126 | memset(_ssbss, 0, _esbss-_ssbss); |
@@ -119,27 +142,15 @@ void __init machine_early_init(const char *cmdline, unsigned int ram, | |||
119 | printk(KERN_NOTICE "Found FDT at 0x%08x\n", fdt); | 142 | printk(KERN_NOTICE "Found FDT at 0x%08x\n", fdt); |
120 | 143 | ||
121 | #ifdef CONFIG_MTD_UCLINUX | 144 | #ifdef CONFIG_MTD_UCLINUX |
122 | { | 145 | early_printk("Found romfs @ 0x%08x (0x%08x)\n", |
123 | int size; | 146 | romfs_base, romfs_size); |
124 | unsigned int romfs_base; | 147 | early_printk("#### klimit %p ####\n", old_klimit); |
125 | romfs_base = (ram ? ram : (unsigned int)&__init_end); | 148 | BUG_ON(romfs_size < 0); /* What else can we do? */ |
126 | /* if CONFIG_MTD_UCLINUX_EBSS is defined, assume ROMFS is at the | 149 | |
127 | * end of kernel, which is ROMFS_LOCATION defined above. */ | 150 | early_printk("Moved 0x%08x bytes from 0x%08x to 0x%08x\n", |
128 | size = PAGE_ALIGN(get_romfs_len((unsigned *)romfs_base)); | 151 | romfs_size, romfs_base, (unsigned)&_ebss); |
129 | early_printk("Found romfs @ 0x%08x (0x%08x)\n", | 152 | |
130 | romfs_base, size); | 153 | early_printk("New klimit: 0x%08x\n", (unsigned)klimit); |
131 | early_printk("#### klimit %p ####\n", klimit); | ||
132 | BUG_ON(size < 0); /* What else can we do? */ | ||
133 | |||
134 | /* Use memmove to handle likely case of memory overlap */ | ||
135 | early_printk("Moving 0x%08x bytes from 0x%08x to 0x%08x\n", | ||
136 | size, romfs_base, (unsigned)&_ebss); | ||
137 | memmove(&_ebss, (int *)romfs_base, size); | ||
138 | |||
139 | /* update klimit */ | ||
140 | klimit += PAGE_ALIGN(size); | ||
141 | early_printk("New klimit: 0x%08x\n", (unsigned)klimit); | ||
142 | } | ||
143 | #endif | 154 | #endif |
144 | 155 | ||
145 | for (src = __ivt_start; src < __ivt_end; src++, dst++) | 156 | for (src = __ivt_start; src < __ivt_end; src++, dst++) |