Commit d40eb7a2 authored by Russell King's avatar Russell King

[ARM] Parse initrd information early

We need the initrd location before the normal command line parsing
occurs so we can reserve the right bits of memory, and not double-
free the initrd during userspace boot.
parent 2e5010c5
...@@ -81,6 +81,8 @@ struct cpu_user_fns cpu_user; ...@@ -81,6 +81,8 @@ struct cpu_user_fns cpu_user;
unsigned char aux_device_present; unsigned char aux_device_present;
char elf_platform[ELF_PLATFORM_SIZE]; char elf_platform[ELF_PLATFORM_SIZE];
char saved_command_line[COMMAND_LINE_SIZE]; char saved_command_line[COMMAND_LINE_SIZE];
unsigned long phys_initrd_start __initdata = 0;
unsigned long phys_initrd_size __initdata = 0;
static struct meminfo meminfo __initdata = { 0, }; static struct meminfo meminfo __initdata = { 0, };
static struct proc_info_item proc_info; static struct proc_info_item proc_info;
...@@ -330,6 +332,22 @@ parse_cmdline(struct meminfo *mi, char **cmdline_p, char *from) ...@@ -330,6 +332,22 @@ parse_cmdline(struct meminfo *mi, char **cmdline_p, char *from)
mi->bank[mi->nr_banks].size = size; mi->bank[mi->nr_banks].size = size;
mi->bank[mi->nr_banks].node = PHYS_TO_NID(start); mi->bank[mi->nr_banks].node = PHYS_TO_NID(start);
mi->nr_banks += 1; mi->nr_banks += 1;
} else if (c == ' ' && !memcmp(from, "initrd=", 7)) {
unsigned long start, size;
/*
* Remove space character
*/
if (to != command_line)
to -= 1;
start = memparse(from + 7, &from);
if (*from == ',') {
size = memparse(from + 1, &from);
phys_initrd_start = start;
phys_initrd_size = size;
}
} }
c = *from++; c = *from++;
if (!c) if (!c)
...@@ -357,19 +375,6 @@ setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz) ...@@ -357,19 +375,6 @@ setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
#endif #endif
} }
/*
* initial ram disk
*/
static void __init setup_initrd(unsigned int start, unsigned int size)
{
#ifdef CONFIG_BLK_DEV_INITRD
if (start == 0)
size = 0;
initrd_start = start;
initrd_end = start + size;
#endif
}
static void __init static void __init
request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc) request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc)
{ {
...@@ -503,7 +508,8 @@ __tagtable(ATAG_RAMDISK, parse_tag_ramdisk); ...@@ -503,7 +508,8 @@ __tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
static int __init parse_tag_initrd(const struct tag *tag) static int __init parse_tag_initrd(const struct tag *tag)
{ {
setup_initrd(tag->u.initrd.start, tag->u.initrd.size); phys_initrd_start = __virt_to_phys(tag->u.initrd.start);
phys_initrd_size = tag->u.initrd.size;
return 0; return 0;
} }
...@@ -511,13 +517,8 @@ __tagtable(ATAG_INITRD, parse_tag_initrd); ...@@ -511,13 +517,8 @@ __tagtable(ATAG_INITRD, parse_tag_initrd);
static int __init parse_tag_initrd2(const struct tag *tag) static int __init parse_tag_initrd2(const struct tag *tag)
{ {
unsigned long start = 0; phys_initrd_start = tag->u.initrd.start;
phys_initrd_size = tag->u.initrd.size;
if (tag->u.initrd.size) {
start = (unsigned long)phys_to_virt(tag->u.initrd.start);
setup_initrd(start, tag->u.initrd.size);
}
return 0; return 0;
} }
......
...@@ -52,6 +52,8 @@ mmu_gather_t mmu_gathers[NR_CPUS]; ...@@ -52,6 +52,8 @@ mmu_gather_t mmu_gathers[NR_CPUS];
extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
extern char _stext, _text, _etext, _end, __init_begin, __init_end; extern char _stext, _text, _etext, _end, __init_begin, __init_end;
extern unsigned long phys_initrd_start;
extern unsigned long phys_initrd_size;
/* /*
* The sole use of this is to pass memory configuration * The sole use of this is to pass memory configuration
...@@ -254,18 +256,17 @@ find_memend_and_nodes(struct meminfo *mi, struct node_info *np) ...@@ -254,18 +256,17 @@ find_memend_and_nodes(struct meminfo *mi, struct node_info *np)
static int __init check_initrd(struct meminfo *mi) static int __init check_initrd(struct meminfo *mi)
{ {
int initrd_node = -2; int initrd_node = -2;
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
unsigned long end = phys_initrd_start + phys_initrd_size;
/* /*
* Make sure that the initrd is within a valid area of * Make sure that the initrd is within a valid area of
* memory. * memory.
*/ */
if (initrd_start) { if (phys_initrd_size) {
unsigned long phys_initrd_start, phys_initrd_end;
unsigned int i; unsigned int i;
phys_initrd_start = __pa(initrd_start); initrd_node = -1;
phys_initrd_end = __pa(initrd_end);
for (i = 0; i < mi->nr_banks; i++) { for (i = 0; i < mi->nr_banks; i++) {
unsigned long bank_end; unsigned long bank_end;
...@@ -273,7 +274,7 @@ static int __init check_initrd(struct meminfo *mi) ...@@ -273,7 +274,7 @@ static int __init check_initrd(struct meminfo *mi)
bank_end = mi->bank[i].start + mi->bank[i].size; bank_end = mi->bank[i].start + mi->bank[i].size;
if (mi->bank[i].start <= phys_initrd_start && if (mi->bank[i].start <= phys_initrd_start &&
phys_initrd_end <= bank_end) end <= bank_end)
initrd_node = mi->bank[i].node; initrd_node = mi->bank[i].node;
} }
} }
...@@ -281,8 +282,8 @@ static int __init check_initrd(struct meminfo *mi) ...@@ -281,8 +282,8 @@ static int __init check_initrd(struct meminfo *mi)
if (initrd_node == -1) { if (initrd_node == -1) {
printk(KERN_ERR "initrd (0x%08lx - 0x%08lx) extends beyond " printk(KERN_ERR "initrd (0x%08lx - 0x%08lx) extends beyond "
"physical memory - disabling initrd\n", "physical memory - disabling initrd\n",
initrd_start, initrd_end); phys_initrd_start, end);
initrd_start = initrd_end = 0; phys_initrd_start = phys_initrd_size = 0;
} }
#endif #endif
...@@ -423,9 +424,12 @@ void __init bootmem_init(struct meminfo *mi) ...@@ -423,9 +424,12 @@ void __init bootmem_init(struct meminfo *mi)
#ifdef CONFIG_BLK_DEV_INITRD #ifdef CONFIG_BLK_DEV_INITRD
if (initrd_node >= 0) if (phys_initrd_size && initrd_node >= 0) {
reserve_bootmem_node(NODE_DATA(initrd_node), __pa(initrd_start), reserve_bootmem_node(NODE_DATA(initrd_node), phys_initrd_start,
initrd_end - initrd_start); phys_initrd_size);
initrd_start = __phys_to_virt(phys_initrd_start);
initrd_end = initrd_start + phys_initrd_size;
}
#endif #endif
if (map_pg != bootmap_pfn + bootmap_pages) if (map_pg != bootmap_pfn + bootmap_pages)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment