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;
unsigned char aux_device_present;
char elf_platform[ELF_PLATFORM_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 proc_info_item proc_info;
......@@ -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].node = PHYS_TO_NID(start);
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++;
if (!c)
......@@ -357,19 +375,6 @@ setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
#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
request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc)
{
......@@ -503,7 +508,8 @@ __tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
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;
}
......@@ -511,13 +517,8 @@ __tagtable(ATAG_INITRD, parse_tag_initrd);
static int __init parse_tag_initrd2(const struct tag *tag)
{
unsigned long start = 0;
if (tag->u.initrd.size) {
start = (unsigned long)phys_to_virt(tag->u.initrd.start);
setup_initrd(start, tag->u.initrd.size);
}
phys_initrd_start = tag->u.initrd.start;
phys_initrd_size = tag->u.initrd.size;
return 0;
}
......
......@@ -52,6 +52,8 @@ mmu_gather_t mmu_gathers[NR_CPUS];
extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
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
......@@ -254,18 +256,17 @@ find_memend_and_nodes(struct meminfo *mi, struct node_info *np)
static int __init check_initrd(struct meminfo *mi)
{
int initrd_node = -2;
#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
* memory.
*/
if (initrd_start) {
unsigned long phys_initrd_start, phys_initrd_end;
if (phys_initrd_size) {
unsigned int i;
phys_initrd_start = __pa(initrd_start);
phys_initrd_end = __pa(initrd_end);
initrd_node = -1;
for (i = 0; i < mi->nr_banks; i++) {
unsigned long bank_end;
......@@ -273,7 +274,7 @@ static int __init check_initrd(struct meminfo *mi)
bank_end = mi->bank[i].start + mi->bank[i].size;
if (mi->bank[i].start <= phys_initrd_start &&
phys_initrd_end <= bank_end)
end <= bank_end)
initrd_node = mi->bank[i].node;
}
}
......@@ -281,8 +282,8 @@ static int __init check_initrd(struct meminfo *mi)
if (initrd_node == -1) {
printk(KERN_ERR "initrd (0x%08lx - 0x%08lx) extends beyond "
"physical memory - disabling initrd\n",
initrd_start, initrd_end);
initrd_start = initrd_end = 0;
phys_initrd_start, end);
phys_initrd_start = phys_initrd_size = 0;
}
#endif
......@@ -423,9 +424,12 @@ void __init bootmem_init(struct meminfo *mi)
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_node >= 0)
reserve_bootmem_node(NODE_DATA(initrd_node), __pa(initrd_start),
initrd_end - initrd_start);
if (phys_initrd_size && initrd_node >= 0) {
reserve_bootmem_node(NODE_DATA(initrd_node), phys_initrd_start,
phys_initrd_size);
initrd_start = __phys_to_virt(phys_initrd_start);
initrd_end = initrd_start + phys_initrd_size;
}
#endif
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