Commit b2a2a84d authored by Hervé Fache's avatar Hervé Fache Committed by David Woodhouse

mtd: phram: dot not crash when built-in and passing boot param

This patch is based on Ville Herva's similar patch to block2mtd.

Trying to pass a parameter through the kernel command line when built-in would
crash the kernel, as phram_setup() was called so early that kmalloc() was not
functional yet.

This patch only saves the parameter string at the early boot stage, and parses
it later when init_phram() is called. The same happens in both module and
built-in cases.

With this patch, I can boot with a statically-compiled phram, and mount a
ext2 root fs from physical RAM, without the need for a initrd.

This has been tested in built-in and module cases, with and without a
parameter string.

Artem: amended comments a bit
Signed-off-by: default avatarHervé Fache <h-fache@ti.com>
Signed-off-by: default avatarArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent 09ef90d9
...@@ -39,7 +39,8 @@ static int phram_erase(struct mtd_info *mtd, struct erase_info *instr) ...@@ -39,7 +39,8 @@ static int phram_erase(struct mtd_info *mtd, struct erase_info *instr)
memset(start + instr->addr, 0xff, instr->len); memset(start + instr->addr, 0xff, instr->len);
/* This'll catch a few races. Free the thing before returning :) /*
* This'll catch a few races. Free the thing before returning :)
* I don't feel at all ashamed. This kind of thing is possible anyway * I don't feel at all ashamed. This kind of thing is possible anyway
* with flash, but unlikely. * with flash, but unlikely.
*/ */
...@@ -204,7 +205,17 @@ static inline void kill_final_newline(char *str) ...@@ -204,7 +205,17 @@ static inline void kill_final_newline(char *str)
return 1; \ return 1; \
} while (0) } while (0)
static int phram_setup(const char *val, struct kernel_param *kp) /*
* This shall contain the module parameter if any. It is of the form:
* - phram=<device>,<address>,<size> for module case
* - phram.phram=<device>,<address>,<size> for built-in case
* We leave 64 bytes for the device name, 12 for the address and 12 for the
* size.
* Example: phram.phram=rootfs,0xa0000000,512Mi
*/
static __initdata char phram_paramline[64+12+12];
static int phram_setup(const char *val)
{ {
char buf[64+12+12], *str = buf; char buf[64+12+12], *str = buf;
char *token[3]; char *token[3];
...@@ -253,12 +264,28 @@ static int phram_setup(const char *val, struct kernel_param *kp) ...@@ -253,12 +264,28 @@ static int phram_setup(const char *val, struct kernel_param *kp)
return ret; return ret;
} }
module_param_call(phram, phram_setup, NULL, NULL, 000); static int __init phram_param_call(const char *val, struct kernel_param *kp)
{
/*
* This function is always called before 'init_phram()', whether
* built-in or module.
*/
if (strlen(val) >= sizeof(phram_paramline))
return -ENOSPC;
strcpy(phram_paramline, val);
return 0;
}
module_param_call(phram, phram_param_call, NULL, NULL, 000);
MODULE_PARM_DESC(phram, "Memory region to map. \"phram=<name>,<start>,<length>\""); MODULE_PARM_DESC(phram, "Memory region to map. \"phram=<name>,<start>,<length>\"");
static int __init init_phram(void) static int __init init_phram(void)
{ {
if (phram_paramline[0])
return phram_setup(phram_paramline);
return 0; return 0;
} }
......
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