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 <libubox/ulog.h>
26 #include "libubi/libubi-tiny.h"
28 static int print_usage(void)
31 printf("ubi detach kernel|rootfs\n");
32 printf("ubi kernel <image.kernel.ubi>\n");
33 printf("ubi rootfs <image.rootfs.ubi>\n");
34 printf("ubi overlay <image.rootfs-overlay.ubi>\n");
39 static int mtd_find_index(char *name
)
41 FILE *fp
= fopen("/proc/mtd", "r");
48 while (!index
&& fgets(line
, sizeof(line
), fp
)) {
49 if (strstr(line
, name
)) {
50 char *eol
= strstr(line
, ":");
68 static int mtd_find(char *name
, char *ret
)
70 int index
= mtd_find_index(name
);
74 sprintf(ret
, "/dev/mtd%d", index
);
79 static int ubi_find(libubi_t libubi
, char *name
, char *ret
)
81 int index
= mtd_find_index(name
);
84 while (ubi_dev_present(libubi
, ubi
))
86 struct ubi_dev_info info
;
88 if (ubi_get_dev_info1(libubi
, ubi
++, &info
))
91 if (info
.mtd_num
!= index
)
94 sprintf(ret
, "/dev/ubi%d", info
.dev_num
);
102 static int volume_find(libubi_t libubi
, char *name
, char *ret
)
104 int index
= mtd_find_index(name
);
105 struct ubi_vol_info vol
;
111 if (mtd_num2ubi_dev(libubi
, index
, &ubi
)) {
112 ULOG_ERR("failed to get ubi node for %s\n", name
);
116 if (ubi_get_vol_info1_nm(libubi
, ubi
, name
, &vol
)) {
117 ULOG_ERR("failed to get ubi volume info for %s\n", name
);
121 sprintf(ret
, "/dev/ubi%d_%d", ubi
, vol
.vol_id
);
126 static int main_detach(char *type
)
132 if (!strcmp(type
, "kernel"))
133 err
= mtd_find("kernel_ubi", mtd
);
134 else if (!strcmp(type
, "rootfs"))
135 err
= mtd_find("rootfs_ubi", mtd
);
137 return print_usage();
140 ULOG_ERR("MTD partition '%s_ubi' not found\n", type
);
144 libubi
= libubi_open();
146 ULOG_ERR("cannot open libubi");
150 err
= ubidetach(libubi
, mtd
);
152 ULOG_ERR("cannot detach \"%s\"", mtd
);
153 libubi_close(libubi
);
157 libubi_close(libubi
);
161 static int main_image(char *partition
, char *image
, char *overlay
)
173 if (stat(image
, &s
)) {
174 ULOG_ERR("image not found %s\n", image
);
178 if (!strcmp(partition
, "kernel"))
179 err
= mtd_find("kernel", _part
);
181 err
= mtd_find("rootfs", _part
);
183 if (overlay
&& !mtd_find(overlay
, _data
))
186 libubi
= libubi_open();
188 ULOG_ERR("cannot open libubi");
192 if (!strcmp(partition
, "kernel"))
193 err
= mtd_find("kernel_ubi", mtd
);
195 err
= mtd_find("rootfs_ubi", mtd
);
197 ULOG_ERR("MTD partition '%s_ubi' not found\n", partition
);
198 libubi_close(libubi
);
202 if (!strcmp(partition
, "kernel"))
203 err
= ubi_find(libubi
, "kernel_ubi", node
);
205 err
= ubi_find(libubi
, "rootfs_ubi", node
);
207 ULOG_ERR("UBI volume '%s' not found\n", partition
);
208 libubi_close(libubi
);
212 err
= ubidetach(libubi
, mtd
);
214 ULOG_ERR("cannot detach \"%s\"", mtd
);
215 libubi_close(libubi
);
219 err
= ubiattach(libubi
, mtd
);
221 ULOG_ERR("cannot attach \"%s\"", mtd
);
222 libubi_close(libubi
);
227 err
= ubirmvol(libubi
, node
, overlay
);
229 ULOG_ERR("cannot remove \"%s\"", node
);
230 libubi_close(libubi
);
235 if (volume_find(libubi
, partition
, volume
) < 0) {
236 ULOG_ERR("UBI volume '%s' not found\n", partition
);
237 libubi_close(libubi
);
241 err
= ubirsvol(libubi
, node
, partition
, s
.st_size
);
243 ULOG_ERR("cannot resize \"%s\"", partition
);
244 libubi_close(libubi
);
248 err
= ubiupdatevol(libubi
, volume
, image
);
250 ULOG_ERR("cannot update \"%s\"", volume
);
251 libubi_close(libubi
);
256 err
= ubimkvol(libubi
, node
, overlay
, 1);
258 ULOG_ERR("cannot make \"%s\"", overlay
);
259 libubi_close(libubi
);
264 libubi_close(libubi
);
269 static int main_info(void)
271 struct ubi_info info
;
275 libubi
= libubi_open();
277 ULOG_ERR("cannot open libubi");
281 if (ubi_get_info(libubi
, &info
)) {
282 ULOG_ERR("failed to get info\n");
283 libubi_close(libubi
);
287 for (i
= info
.lowest_dev_num
; i
<= info
.highest_dev_num
; i
++) {
288 struct ubi_dev_info dinfo
;
292 sprintf(ubi
, "/dev/ubi%d", i
);
293 if (ubi_get_dev_info(libubi
, ubi
, &dinfo
))
295 printf("device - %s\n size: %lldBytes\n bad blocks: %d\n",
296 &ubi
[5], dinfo
.total_bytes
, dinfo
.bad_count
);
297 for (j
= dinfo
.lowest_vol_id
; j
<= dinfo
.highest_vol_id
; j
++) {
298 struct ubi_vol_info vinfo
;
300 sprintf(ubi
, "/dev/ubi%d_%d", i
, j
);
301 if (ubi_get_vol_info(libubi
, ubi
, &vinfo
))
303 printf(" volume - %s\n", &ubi
[5]);
304 printf("\tname: %s\n", vinfo
.name
);
305 printf("\tsize: %lld\n", vinfo
.data_bytes
);
309 libubi_close(libubi
);
314 int main(int argc
, char **argv
)
316 if (argc
> 1 && !strcmp(argv
[1], "info"))
320 return print_usage();
322 if (!strcmp(argv
[1], "kernel")) {
323 return main_image("kernel", argv
[2], NULL
);
325 } else if (!strcmp(argv
[1], "rootfs")) {
326 return main_image("rootfs", argv
[2], NULL
);
328 } else if (!strcmp(argv
[1], "overlay")) {
329 return main_image("rootfs", argv
[2], "rootfs_data");
331 } else if (!strcmp(argv
[1], "detach")) {
332 return main_detach(argv
[2]);