7cb8d62340e7f4dec7ac7da938a1ac3664edd4df
2 * Copyright (C) 2014 John Crispin <blogic@openwrt.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 2.1
6 * as published by the Free Software Foundation
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
14 #include <sys/types.h>
24 #include "libubi/libubi-tiny.h"
26 static int mtd_find_index(char *name
)
28 FILE *fp
= fopen("/proc/mtd", "r");
35 while (!index
&& fgets(line
, sizeof(line
), fp
)) {
36 if (strstr(line
, name
)) {
37 char *eol
= strstr(line
, ":");
55 static int mtd_find(char *name
, char *ret
)
57 int index
= mtd_find_index(name
);
61 sprintf(ret
, "/dev/mtd%d", index
);
66 static int ubi_find(libubi_t libubi
, char *name
, char *ret
)
68 int index
= mtd_find_index(name
);
74 if (mtd_num2ubi_dev(libubi
, index
, &ubi
)) {
75 fprintf(stderr
, "failed to get ubi node for %s\n", name
);
78 sprintf(ret
, "/dev/ubi%d", ubi
);
83 static int ubi_find_mtd(libubi_t libubi
, char *name
, char *ret
)
85 struct ubi_dev_info info
;
87 if (ubi_find(libubi
, name
, ret
))
90 if (ubi_get_dev_info(libubi
, ret
, &info
))
93 sprintf(ret
, "/dev/mtd%d", info
.mtd_num
);
98 static int volume_find(libubi_t libubi
, char *name
, char *ret
)
100 int index
= mtd_find_index(name
);
101 struct ubi_vol_info vol
;
107 if (mtd_num2ubi_dev(libubi
, index
, &ubi
)) {
108 fprintf(stderr
, "failed to get ubi node for %s\n", name
);
112 if (ubi_get_vol_info1_nm(libubi
, ubi
, name
, &vol
)) {
113 fprintf(stderr
, "failed to get ubi volume info for %s\n", name
);
117 sprintf(ret
, "/dev/ubi%d_%d", ubi
, vol
.vol_id
);
122 static int main_image(char *partition
, char *image
, char *overlay
)
133 if (mtd_find(partition
, part
)) {
134 fprintf(stderr
, "failed to find mtd partition %s\n", partition
);
137 if (overlay
&& !mtd_find(overlay
, _data
))
140 libubi
= libubi_open();
142 fprintf(stderr
, "cannot open libubi");
146 if (ubi_find_mtd(libubi
, partition
, mtd
)) {
147 fprintf(stderr
, "failed to find mtd parent %s\n", partition
);
151 if (ubi_find(libubi
, partition
, node
)) {
152 fprintf(stderr
, "failed to find ubi volume %s\n", partition
);
156 if (volume_find(libubi
, partition
, volume
)) {
157 fprintf(stderr
, "failed to find ubi volume %s\n", partition
);
161 err
= ubidetach(libubi
, mtd
);
163 fprintf(stderr
, "cannot detach \"%s\"", mtd
);
167 err
= ubiattach(libubi
, mtd
);
169 fprintf(stderr
, "cannot attach \"%s\"", mtd
);
174 err
= ubirmvol(libubi
, node
, overlay
);
176 fprintf(stderr
, "cannot remove \"%s\"", node
);
181 err
= ubiupdatevol(libubi
, volume
, image
);
183 fprintf(stderr
, "cannot update \"%s\"", volume
);
188 err
= ubimkvol(libubi
, node
, overlay
, 1);
190 fprintf(stderr
, "cannot make \"%s\"", node
);
195 libubi_close(libubi
);
200 static int main_info(void)
202 struct ubi_info info
;
206 libubi
= libubi_open();
208 fprintf(stderr
, "cannot open libubi");
212 if (ubi_get_info(libubi
, &info
)) {
213 fprintf(stderr
, "failed to get info\n");
217 for (i
= info
.lowest_dev_num
; i
<= info
.highest_dev_num
; i
++) {
218 struct ubi_dev_info dinfo
;
222 sprintf(ubi
, "/dev/ubi%d", i
);
223 if (ubi_get_dev_info(libubi
, ubi
, &dinfo
))
225 printf("device - %s\n size: %lldBytes\n bad blocks: %d\n",
226 &ubi
[5], dinfo
.total_bytes
, dinfo
.bad_count
);
227 for (j
= dinfo
.lowest_vol_id
; j
<= dinfo
.highest_vol_id
; j
++) {
228 struct ubi_vol_info vinfo
;
230 sprintf(ubi
, "/dev/ubi%d_%d", i
, j
);
231 if (ubi_get_vol_info(libubi
, ubi
, &vinfo
))
233 printf(" volume - %s\n", &ubi
[5]);
234 printf("\tname: %s\n", vinfo
.name
);
235 printf("\tsize: %lld\n", vinfo
.data_bytes
);
239 libubi_close(libubi
);
244 static int print_usage(void)
246 printf("ubi info\n");
247 printf("ubi kernel <image.kernel.ubifs>\n");
248 printf("ubi rootfs <image.rootfs.ubifs>\n");
249 printf("ubi overlay <image.rootfs-overlay.ubifs>\n");
254 int main(int argc
, char **argv
)
256 if (argc
> 1 && !strcmp(argv
[1], "info"))
260 return print_usage();
262 if (!strcmp(argv
[1], "kernel")) {
263 return main_image("kernel", argv
[2], NULL
);
265 } else if (!strcmp(argv
[1], "rootfs")) {
266 return main_image("rootfs", argv
[2], NULL
);
268 } else if (!strcmp(argv
[1], "overlay")) {
269 return main_image("rootfs", argv
[2], "rootfs_data");