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

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Mon Mar 26 20:59:17 EDT 2012


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=b2a2a84d35e0f42ad26e326ec4258f6a8b8eecbe
Commit:     b2a2a84d35e0f42ad26e326ec4258f6a8b8eecbe
Parent:     09ef90d965fff295da8d5359ac21e54c02236dba
Author:     Hervé Fache <h-fache at ti.com>
AuthorDate: Tue Mar 13 16:07:53 2012 +0100
Committer:  David Woodhouse <David.Woodhouse at intel.com>
CommitDate: Tue Mar 27 00:57:11 2012 +0100

    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: Hervé Fache <h-fache at ti.com>
    Signed-off-by: Artem Bityutskiy <artem.bityutskiy at linux.intel.com>
    Signed-off-by: David Woodhouse <David.Woodhouse at intel.com>
---
 drivers/mtd/devices/phram.c |   33 ++++++++++++++++++++++++++++++---
 1 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c
index 9d2bf17..3d91ace 100644
--- a/drivers/mtd/devices/phram.c
+++ b/drivers/mtd/devices/phram.c
@@ -39,7 +39,8 @@ static int phram_erase(struct mtd_info *mtd, struct erase_info *instr)
 
 	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
 	 * with flash, but unlikely.
 	 */
@@ -204,7 +205,17 @@ static inline void kill_final_newline(char *str)
 	return 1;		\
 } 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 *token[3];
@@ -253,12 +264,28 @@ static int phram_setup(const char *val, struct kernel_param *kp)
 	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>\"");
 
 
 static int __init init_phram(void)
 {
+	if (phram_paramline[0])
+		return phram_setup(phram_paramline);
+
 	return 0;
 }
 



More information about the linux-mtd-cvs mailing list