// SPDX-License-Identifier: GPL-2.0-or-later /* * Read flash partition table from command line * * Copyright © 2002 SYSGO Real-Time Solutions GmbH * Copyright © 2002-2010 David Woodhouse <[email protected]> * * The format for the command line is as follows: * * mtdparts=<mtddef>[;<mtddef] * <mtddef> := <mtd-id>:<partdef>[,<partdef>] * <partdef> := <size>[@<offset>][<name>][ro][lk][slc] * <mtd-id> := unique name used in mapping driver/device (mtd->name) * <size> := standard linux memsize OR "-" to denote all remaining space * size is automatically truncated at end of device * if specified or truncated size is 0 the part is skipped * <offset> := standard linux memsize * if omitted the part will immediately follow the previous part * or 0 if the first part * <name> := '(' NAME ')' * NAME will appear in /proc/mtd * * <size> and <offset> can be specified such that the parts are out of order * in physical memory and may even overlap. * * The parts are assigned MTD numbers in the order they are specified in the * command line regardless of their order in physical memory. * * Examples: * * 1 NOR Flash, with 1 single writable partition: * edb7312-nor:- * * 1 NOR Flash with 2 partitions, 1 NAND with one * edb7312-nor:256k(ARMboot)ro,-(root);edb7312-nand:-(home) */ #define pr_fmt(fmt) … #include <linux/kernel.h> #include <linux/slab.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/module.h> #include <linux/err.h> /* special size referring to all the remaining space in a partition */ #define SIZE_REMAINING … #define OFFSET_CONTINUOUS … struct cmdline_mtd_partition { … }; /* mtdpart_setup() parses into here */ static struct cmdline_mtd_partition *partitions; /* the command line passed to mtdpart_setup() */ static char *mtdparts; static char *cmdline; static int cmdline_parsed; /* * Parse one partition definition for an MTD. Since there can be many * comma separated partition definitions, this function calls itself * recursively until no more partition definitions are found. Nice side * effect: the memory to keep the mtd_partition structs and the names * is allocated upon the last definition being found. At that point the * syntax has been verified ok. */ static struct mtd_partition * newpart(char *s, char **retptr, int *num_parts, int this_part, unsigned char **extra_mem_ptr, int extra_mem_size) { … } /* * Parse the command line. */ static int mtdpart_setup_real(char *s) { … } /* * Main function to be called from the MTD mapping driver/device to * obtain the partitioning information. At this point the command line * arguments will actually be parsed and turned to struct mtd_partition * information. It returns partitions for the requested mtd device, or * the first one in the chain if a NULL mtd_id is passed in. */ static int parse_cmdline_partitions(struct mtd_info *master, const struct mtd_partition **pparts, struct mtd_part_parser_data *data) { … } /* * This is the handler for our kernel parameter, called from * main.c::checksetup(). Note that we can not yet kmalloc() anything, * so we only save the commandline for later processing. * * This function needs to be visible for bootloaders. */ static int __init mtdpart_setup(char *s) { … } __setup(…); static struct mtd_part_parser cmdline_parser = …; static int __init cmdline_parser_init(void) { … } static void __exit cmdline_parser_exit(void) { … } module_init(…) …; module_exit(cmdline_parser_exit); MODULE_PARM_DESC(…) …; module_param(mtdparts, charp, 0); MODULE_LICENSE(…) …; MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …;