1 /* 2 * Copyright (C) 2014 John Crispin <blogic@openwrt.org> 3 * 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 7 * 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. 12 */ 13 14 #include <sys/types.h> 15 #include <sys/stat.h> 16 #include <fcntl.h> 17 #include <stdio.h> 18 #include <stdint.h> 19 #include <getopt.h> 20 #include <stdlib.h> 21 #include <string.h> 22 #include <unistd.h> 23 24 #include <libubox/ulog.h> 25 26 #include "libubi/libubi-tiny.h" 27 28 static int print_usage(void) 29 { 30 printf("ubi info\n"); 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"); 35 36 return -1; 37 } 38 39 static int mtd_find_index(char *name) 40 { 41 FILE *fp = fopen("/proc/mtd", "r"); 42 char line[256]; 43 char *index = NULL; 44 45 if (!fp) 46 return -1; 47 48 while (!index && fgets(line, sizeof(line), fp)) { 49 if (strstr(line, name)) { 50 char *eol = strstr(line, ":"); 51 52 if (!eol) 53 continue; 54 55 *eol = '\0'; 56 index = &line[3]; 57 } 58 } 59 60 fclose(fp); 61 62 if (!index) 63 return -1; 64 65 return atoi(index); 66 } 67 68 static int mtd_find(char *name, char *ret) 69 { 70 int index = mtd_find_index(name); 71 if (index < 0) 72 return -1; 73 74 sprintf(ret, "/dev/mtd%d", index); 75 76 return 0; 77 } 78 79 static int ubi_find(libubi_t libubi, char *name, char *ret) 80 { 81 int index = mtd_find_index(name); 82 int ubi = 0; 83 84 while (ubi_dev_present(libubi, ubi)) 85 { 86 struct ubi_dev_info info; 87 88 if (ubi_get_dev_info1(libubi, ubi++, &info)) 89 continue; 90 91 if (info.mtd_num != index) 92 continue; 93 94 sprintf(ret, "/dev/ubi%d", info.dev_num); 95 96 return 0; 97 } 98 99 return -1; 100 } 101 102 static int volume_find(libubi_t libubi, char *name, char *ret) 103 { 104 int index = mtd_find_index(name); 105 struct ubi_vol_info vol; 106 int ubi = 0; 107 108 if (index < 0) 109 return -1; 110 111 if (mtd_num2ubi_dev(libubi, index, &ubi)) { 112 ULOG_ERR("failed to get ubi node for %s\n", name); 113 return -1; 114 } 115 116 if (ubi_get_vol_info1_nm(libubi, ubi, name, &vol)) { 117 ULOG_ERR("failed to get ubi volume info for %s\n", name); 118 return -1; 119 } 120 121 sprintf(ret, "/dev/ubi%d_%d", ubi, vol.vol_id); 122 123 return 0; 124 } 125 126 static int main_detach(char *type) 127 { 128 libubi_t libubi; 129 char mtd[64]; 130 int err; 131 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); 136 else 137 return print_usage(); 138 139 if (err) { 140 ULOG_ERR("MTD partition '%s_ubi' not found\n", type); 141 return -1; 142 } 143 144 libubi = libubi_open(); 145 if (!libubi) { 146 ULOG_ERR("cannot open libubi"); 147 return -1; 148 } 149 150 err = ubidetach(libubi, mtd); 151 if (err) { 152 ULOG_ERR("cannot detach \"%s\"", mtd); 153 libubi_close(libubi); 154 return -1; 155 } 156 157 libubi_close(libubi); 158 return 0; 159 } 160 161 static int main_image(char *partition, char *image, char *overlay) 162 { 163 libubi_t libubi; 164 struct stat s; 165 int err; 166 char mtd[64]; 167 char _part[64]; 168 char node[64]; 169 char volume[64]; 170 char _data[64]; 171 char *data = NULL; 172 173 if (stat(image, &s)) { 174 ULOG_ERR("image not found %s\n", image); 175 return -1; 176 } 177 178 if (!strcmp(partition, "kernel")) 179 err = mtd_find("kernel", _part); 180 else 181 err = mtd_find("rootfs", _part); 182 183 if (overlay && !mtd_find(overlay, _data)) 184 data = _data; 185 186 libubi = libubi_open(); 187 if (!libubi) { 188 ULOG_ERR("cannot open libubi"); 189 return -1; 190 } 191 192 if (!strcmp(partition, "kernel")) 193 err = mtd_find("kernel_ubi", mtd); 194 else 195 err = mtd_find("rootfs_ubi", mtd); 196 if (err) { 197 ULOG_ERR("MTD partition '%s_ubi' not found\n", partition); 198 libubi_close(libubi); 199 return -1; 200 } 201 202 if (!strcmp(partition, "kernel")) 203 err = ubi_find(libubi, "kernel_ubi", node); 204 else 205 err = ubi_find(libubi, "rootfs_ubi", node); 206 if (err) { 207 ULOG_ERR("UBI volume '%s' not found\n", partition); 208 libubi_close(libubi); 209 return -1; 210 } 211 212 err = ubidetach(libubi, mtd); 213 if (err) { 214 ULOG_ERR("cannot detach \"%s\"", mtd); 215 libubi_close(libubi); 216 return -1; 217 } 218 219 err = ubiattach(libubi, mtd); 220 if (err) { 221 ULOG_ERR("cannot attach \"%s\"", mtd); 222 libubi_close(libubi); 223 return -1; 224 } 225 226 if (data) { 227 err = ubirmvol(libubi, node, overlay); 228 if (err) { 229 ULOG_ERR("cannot remove \"%s\"", node); 230 libubi_close(libubi); 231 return -1; 232 } 233 } 234 235 if (volume_find(libubi, partition, volume) < 0) { 236 ULOG_ERR("UBI volume '%s' not found\n", partition); 237 libubi_close(libubi); 238 return -1; 239 } 240 241 err = ubirsvol(libubi, node, partition, s.st_size); 242 if (err) { 243 ULOG_ERR("cannot resize \"%s\"", partition); 244 libubi_close(libubi); 245 return -1; 246 } 247 248 err = ubiupdatevol(libubi, volume, image); 249 if (err) { 250 ULOG_ERR("cannot update \"%s\"", volume); 251 libubi_close(libubi); 252 return -1; 253 } 254 255 if (overlay) { 256 err = ubimkvol(libubi, node, overlay, 1); 257 if (err) { 258 ULOG_ERR("cannot make \"%s\"", overlay); 259 libubi_close(libubi); 260 return -1; 261 } 262 } 263 264 libubi_close(libubi); 265 266 return err; 267 } 268 269 static int main_info(void) 270 { 271 struct ubi_info info; 272 libubi_t libubi; 273 int i; 274 275 libubi = libubi_open(); 276 if (!libubi) { 277 ULOG_ERR("cannot open libubi"); 278 return -1; 279 } 280 281 if (ubi_get_info(libubi, &info)) { 282 ULOG_ERR("failed to get info\n"); 283 libubi_close(libubi); 284 return -1; 285 } 286 287 for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) { 288 struct ubi_dev_info dinfo; 289 char ubi[64]; 290 int j; 291 292 sprintf(ubi, "/dev/ubi%d", i); 293 if (ubi_get_dev_info(libubi, ubi, &dinfo)) 294 continue; 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; 299 300 sprintf(ubi, "/dev/ubi%d_%d", i, j); 301 if (ubi_get_vol_info(libubi, ubi, &vinfo)) 302 continue; 303 printf(" volume - %s\n", &ubi[5]); 304 printf("\tname: %s\n", vinfo.name); 305 printf("\tsize: %lld\n", vinfo.data_bytes); 306 } 307 } 308 309 libubi_close(libubi); 310 311 return 0; 312 } 313 314 int main(int argc, char **argv) 315 { 316 if (argc > 1 && !strcmp(argv[1], "info")) 317 return main_info(); 318 319 if (argc < 3) 320 return print_usage(); 321 322 if (!strcmp(argv[1], "kernel")) { 323 return main_image("kernel", argv[2], NULL); 324 325 } else if (!strcmp(argv[1], "rootfs")) { 326 return main_image("rootfs", argv[2], NULL); 327 328 } else if (!strcmp(argv[1], "overlay")) { 329 return main_image("rootfs", argv[2], "rootfs_data"); 330 331 } else if (!strcmp(argv[1], "detach")) { 332 return main_detach(argv[2]); 333 } 334 335 return -1; 336 } 337 338
This page was automatically generated by LXR 0.3.1. • OpenWrt