#include <string.h>
#include <unistd.h>
+#include <libubox/ulog.h>
+
#include "libubi/libubi-tiny.h"
+static int print_usage(void)
+{
+ printf("ubi info\n");
+ printf("ubi detach kernel|rootfs\n");
+ printf("ubi kernel <image.kernel.ubi>\n");
+ printf("ubi rootfs <image.rootfs.ubi>\n");
+ printf("ubi overlay <image.rootfs-overlay.ubi>\n");
+
+ return -1;
+}
+
static int mtd_find_index(char *name)
{
FILE *fp = fopen("/proc/mtd", "r");
int index = mtd_find_index(name);
int ubi = 0;
- if (index < 0)
- return -1;
-
- if (mtd_num2ubi_dev(libubi, index, &ubi)) {
- fprintf(stderr, "failed to get ubi node for %s\n", name);
- return -1;
- }
- sprintf(ret, "/dev/ubi%d", ubi);
-
- return 0;
-}
+ while (ubi_dev_present(libubi, ubi))
+ {
+ struct ubi_dev_info info;
-static int ubi_find_mtd(libubi_t libubi, char *name, char *ret)
-{
- struct ubi_dev_info info;
+ if (ubi_get_dev_info1(libubi, ubi++, &info))
+ continue;
- if (ubi_find(libubi, name, ret))
- return -1;
+ if (info.mtd_num != index)
+ continue;
- if (ubi_get_dev_info(libubi, ret, &info))
- return -1;
+ sprintf(ret, "/dev/ubi%d", info.dev_num);
- sprintf(ret, "/dev/mtd%d", info.mtd_num);
+ return 0;
+ }
- return 0;
+ return -1;
}
static int volume_find(libubi_t libubi, char *name, char *ret)
return -1;
if (mtd_num2ubi_dev(libubi, index, &ubi)) {
- fprintf(stderr, "failed to get ubi node for %s\n", name);
+ ULOG_ERR("failed to get ubi node for %s\n", name);
return -1;
}
if (ubi_get_vol_info1_nm(libubi, ubi, name, &vol)) {
- fprintf(stderr, "failed to get ubi volume info for %s\n", name);
+ ULOG_ERR("failed to get ubi volume info for %s\n", name);
return -1;
}
return 0;
}
+static int main_detach(char *type)
+{
+ libubi_t libubi;
+ char mtd[64];
+ int err;
+
+ if (!strcmp(type, "kernel"))
+ err = mtd_find("kernel_ubi", mtd);
+ else if (!strcmp(type, "rootfs"))
+ err = mtd_find("rootfs_ubi", mtd);
+ else
+ return print_usage();
+
+ if (err) {
+ ULOG_ERR("MTD partition '%s_ubi' not found\n", type);
+ return -1;
+ }
+
+ libubi = libubi_open();
+ if (!libubi) {
+ ULOG_ERR("cannot open libubi");
+ return -1;
+ }
+
+ err = ubidetach(libubi, mtd);
+ if (err) {
+ ULOG_ERR("cannot detach \"%s\"", mtd);
+ return -1;
+ }
+
+ return 0;
+}
+
static int main_image(char *partition, char *image, char *overlay)
{
libubi_t libubi;
+ struct stat s;
int err;
char mtd[64];
- char part[64];
+ char _part[64];
char node[64];
char volume[64];
char _data[64];
char *data = NULL;
- if (mtd_find(partition, part)) {
- fprintf(stderr, "failed to find mtd partition %s\n", partition);
+ if (stat(image, &s)) {
+ ULOG_ERR("image not found %s\n", image);
return -1;
}
+
+ if (!strcmp(partition, "kernel"))
+ err = mtd_find("kernel", _part);
+ else
+ err = mtd_find("rootfs", _part);
+
if (overlay && !mtd_find(overlay, _data))
data = _data;
libubi = libubi_open();
if (!libubi) {
- fprintf(stderr, "cannot open libubi");
+ ULOG_ERR("cannot open libubi");
return -1;
}
- if (ubi_find_mtd(libubi, partition, mtd)) {
- fprintf(stderr, "failed to find mtd parent %s\n", partition);
- return -1;
- }
-
- if (ubi_find(libubi, partition, node)) {
- fprintf(stderr, "failed to find ubi volume %s\n", partition);
+ if (!strcmp(partition, "kernel"))
+ err = mtd_find("kernel_ubi", mtd);
+ else
+ err = mtd_find("rootfs_ubi", mtd);
+ if (err) {
+ ULOG_ERR("MTD partition '%s_ubi' not found\n", partition);
return -1;
}
- if (volume_find(libubi, partition, volume)) {
- fprintf(stderr, "failed to find ubi volume %s\n", partition);
+ if (!strcmp(partition, "kernel"))
+ err = ubi_find(libubi, "kernel_ubi", node);
+ else
+ err = ubi_find(libubi, "rootfs_ubi", node);
+ if (err) {
+ ULOG_ERR("UBI volume '%s' not found\n", partition);
return -1;
}
err = ubidetach(libubi, mtd);
if (err) {
- fprintf(stderr, "cannot detach \"%s\"", mtd);
+ ULOG_ERR("cannot detach \"%s\"", mtd);
return -1;
}
err = ubiattach(libubi, mtd);
if (err) {
- fprintf(stderr, "cannot detach \"%s\"", mtd);
+ ULOG_ERR("cannot attach \"%s\"", mtd);
return -1;
}
if (data) {
err = ubirmvol(libubi, node, overlay);
if (err) {
- fprintf(stderr, "cannot remove \"%s\"", node);
+ ULOG_ERR("cannot remove \"%s\"", node);
return -1;
}
}
+ if (volume_find(libubi, partition, volume) < 0) {
+ ULOG_ERR("UBI volume '%s' not found\n", partition);
+ return -1;
+ }
+
+ err = ubirsvol(libubi, node, partition, s.st_size);
+ if (err) {
+ ULOG_ERR("cannot resize \"%s\"", partition);
+ return -1;
+ }
+
err = ubiupdatevol(libubi, volume, image);
if (err) {
- fprintf(stderr, "cannot update \"%s\"", volume);
+ ULOG_ERR("cannot update \"%s\"", volume);
return -1;
}
if (overlay) {
err = ubimkvol(libubi, node, overlay, 1);
if (err) {
- fprintf(stderr, "cannot make \"%s\"", node);
+ ULOG_ERR("cannot make \"%s\"", overlay);
return -1;
}
}
libubi = libubi_open();
if (!libubi) {
- fprintf(stderr, "cannot open libubi");
+ ULOG_ERR("cannot open libubi");
return -1;
}
if (ubi_get_info(libubi, &info)) {
- fprintf(stderr, "failed to get info\n");
+ ULOG_ERR("failed to get info\n");
return -1;
}
if (ubi_get_dev_info(libubi, ubi, &dinfo))
continue;
printf("device - %s\n size: %lldBytes\n bad blocks: %d\n",
- &ubi[5], dinfo.total_bytes, dinfo.bad_count);
+ &ubi[5], dinfo.total_bytes, dinfo.bad_count);
for (j = dinfo.lowest_vol_id; j <= dinfo.highest_vol_id; j++) {
struct ubi_vol_info vinfo;
return 0;
}
-static int print_usage(void)
-{
- printf("ubi info\n");
- printf("ubi kernel <image.kernel.ubi>\n");
- printf("ubi rootfs <image.rootfs.ubi>\n");
- printf("ubi overlay <image.rootfs-overlay.ubi>\n");
-
- return -1;
-}
-
int main(int argc, char **argv)
{
if (argc > 1 && !strcmp(argv[1], "info"))
} else if (!strcmp(argv[1], "overlay")) {
return main_image("rootfs", argv[2], "rootfs_data");
+
+ } else if (!strcmp(argv[1], "detach")) {
+ return main_detach(argv[2]);
}
return -1;