bootu: Allow passing in devices as parameter
[barebox-mini2440.git] / commands / partition.c
blob77949259438d5c8c9072f492a98840cf491ddb3a
1 /*
2 * partition.c - parse a linux-like mtd partition definition and register
3 * the new partitions
5 * Copyright (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
7 * See file CREDITS for list of people who contributed to this
8 * project.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 /**
25 * @file
26 * @brief partition handling and addpart and delpart command
29 #ifdef CONFIG_ENABLE_PARTITION_NOISE
30 # define DEBUG
31 #endif
33 #include <common.h>
34 #include <command.h>
35 #include <driver.h>
36 #include <malloc.h>
37 #include <partition.h>
38 #include <errno.h>
39 #include <xfuncs.h>
40 #include <fs.h>
41 #include <linux/stat.h>
42 #include <libgen.h>
44 #define SIZE_REMAINING ((ulong)-1)
46 static int mtd_part_do_parse_one(char *devname, const char *partstr,
47 char **endp, unsigned long *offset,
48 off_t devsize, size_t *retsize)
50 ulong size;
51 char *end;
52 char buf[PATH_MAX];
53 unsigned long flags = 0;
54 int ret;
56 memset(buf, 0, PATH_MAX);
58 if (*partstr == '-') {
59 size = SIZE_REMAINING;
60 end = (char *)partstr + 1;
61 } else {
62 size = strtoul_suffix(partstr, &end, 0);
65 if (*end == '@')
66 *offset = strtoul_suffix(end+1, &end, 0);
68 if (size == SIZE_REMAINING)
69 size = devsize - *offset;
71 partstr = end;
73 if (*partstr == '(') {
74 partstr++;
75 end = strchr((char *) partstr, ')');
76 if (!end) {
77 printf("could not find matching ')'\n");
78 return -EINVAL;
81 sprintf(buf, "%s.", devname);
82 memcpy(buf + strlen(buf), partstr, end - partstr);
84 end++;
87 if (size + *offset > devsize) {
88 printf("%s: partition end is beyond device\n", buf);
89 return -EINVAL;
92 partstr = end;
94 if (*partstr == 'r' && *(partstr + 1) == 'o') {
95 flags |= PARTITION_READONLY;
96 end = (char *)(partstr + 2);
99 if (endp)
100 *endp = end;
102 *retsize = size;
104 ret = devfs_add_partition(devname, *offset, size, flags, buf);
105 if (ret)
106 printf("cannot create %s: %s\n", buf, strerror(-ret));
107 return ret;
110 static int do_addpart(struct command * cmdtp, int argc, char *argv[])
112 char *devname;
113 char *endp;
114 unsigned long offset = 0;
115 off_t devsize;
116 struct stat s;
118 if (argc != 3)
119 return COMMAND_ERROR_USAGE;
121 if (stat(argv[1], &s)) {
122 perror("addpart");
123 return 1;
125 devsize = s.st_size;
127 devname = basename(argv[1]);
129 endp = argv[2];
131 while (1) {
132 size_t size = 0;
134 if (mtd_part_do_parse_one(devname, endp, &endp, &offset, devsize, &size))
135 return 1;
137 offset += size;
139 if (!*endp)
140 break;
142 if (*endp != ',') {
143 printf("parse error\n");
144 return 1;
146 endp++;
149 return 0;
152 static const __maybe_unused char cmd_addpart_help[] =
153 "Usage: addpart <device> <partition description>\n"
154 "\n"
155 "addpart adds a partition description to a device. The partition description\n"
156 "has the form\n"
157 "size1[@offset1](name1)[ro],size2[@offset2](name2)[ro],...\n"
158 "<device> is the device name under. Size and offset can be given in decimal\n"
159 "or - if prefixed with 0x in hex. Both can have an optional suffix K,M,G.\n"
160 "The size of the last partition can be specified as '-' for the remaining\n"
161 "space of the device.\n"
162 "This format is the same as used in the Linux kernel for cmdline mtd partitions.\n"
163 "\n"
164 "Note: That this command has to be reworked and will probably change it's API.";
166 BAREBOX_CMD_START(addpart)
167 .cmd = do_addpart,
168 .usage = "adds a partition table to a device",
169 BAREBOX_CMD_HELP(cmd_addpart_help)
170 BAREBOX_CMD_END
172 /** @page addpart_command addpart Add a partition to a device
174 * Usage is: addpart \<device> \<partition description>
176 * Adds a partition description to a device. The partition description has the
177 * form
179 * size1[@offset1](name1)[ro],size2[@offset2](name2)[ro],...
181 * \<device> is the device name under. Size and offset can be given in decimal
182 * or - if prefixed with 0x - in hex. Both can have an optional suffix K,M,G.
183 * The size of the last partition can be specified as '-' for the remaining
184 * space of the device.
186 * @note The format is the same as used in the Linux kernel for cmdline mtd
187 * partitions.
189 * @note This command has to be reworked and will probably change it's API.
192 static int do_delpart(struct command * cmdtp, int argc, char *argv[])
194 int i, err;
196 for (i = 1; i < argc; i++) {
197 err = devfs_del_partition(basename(argv[i]));
198 if (err) {
199 printf("cannot delete %s: %s\n", argv[i], strerror(-err));
200 break;
204 return 1;
207 static const __maybe_unused char cmd_delpart_help[] =
208 "Usage: delpart FILE...\n"
209 "Delete partitions previously added to a device with addpart.\n";
211 BAREBOX_CMD_START(delpart)
212 .cmd = do_delpart,
213 .usage = "delete partition(s)",
214 BAREBOX_CMD_HELP(cmd_delpart_help)
215 BAREBOX_CMD_END
217 /** @page delpart_command delpart Delete a partition
219 * Usage is: delpart \<partions>
221 * Delete a partition previously added to a device with addpart.