1 /* 2 * Unsorted Block Image commands 3 * 4 * Copyright (C) 2008 Samsung Electronics 5 * Kyungmin Park <kyungmin.park@samsung.com> 6 * 7 * Copyright 2008-2009 Stefan Roese <sr@denx.de>, DENX Software Engineering 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 */ 13 14 #include <common.h> 15 #include <command.h> 16 #include <exports.h> 17 #include <memalign.h> 18 #include <nand.h> 19 #include <onenand_uboot.h> 20 #include <linux/mtd/mtd.h> 21 #include <linux/mtd/partitions.h> 22 #include <linux/err.h> 23 #include <ubi_uboot.h> 24 #include <linux/errno.h> 25 #include <jffs2/load_kernel.h> 26 27 #undef ubi_msg 28 #define ubi_msg(fmt, ...) printf("UBI: " fmt "\n", ##__VA_ARGS__) 29 30 #define DEV_TYPE_NONE 0 31 #define DEV_TYPE_NAND 1 32 #define DEV_TYPE_ONENAND 2 33 #define DEV_TYPE_NOR 3 34 35 /* Private own data */ 36 static struct ubi_device *ubi; 37 static char buffer[80]; 38 static int ubi_initialized; 39 40 struct selected_dev { 41 char part_name[80]; 42 int selected; 43 int nr; 44 struct mtd_info *mtd_info; 45 }; 46 47 static struct selected_dev ubi_dev; 48 49 #ifdef CONFIG_CMD_UBIFS 50 int ubifs_is_mounted(void); 51 void cmd_ubifs_umount(void); 52 #endif 53 54 static void display_volume_info(struct ubi_device *ubi) 55 { 56 int i; 57 58 for (i = 0; i < (ubi->vtbl_slots + 1); i++) { 59 if (!ubi->volumes[i]) 60 continue; /* Empty record */ 61 ubi_dump_vol_info(ubi->volumes[i]); 62 } 63 } 64 65 static void display_ubi_info(struct ubi_device *ubi) 66 { 67 ubi_msg("MTD device name: \"%s\"", ubi->mtd->name); 68 ubi_msg("MTD device size: %llu MiB", ubi->flash_size >> 20); 69 ubi_msg("physical eraseblock size: %d bytes (%d KiB)", 70 ubi->peb_size, ubi->peb_size >> 10); 71 ubi_msg("logical eraseblock size: %d bytes", ubi->leb_size); 72 ubi_msg("number of good PEBs: %d", ubi->good_peb_count); 73 ubi_msg("number of bad PEBs: %d", ubi->bad_peb_count); 74 ubi_msg("smallest flash I/O unit: %d", ubi->min_io_size); 75 ubi_msg("VID header offset: %d (aligned %d)", 76 ubi->vid_hdr_offset, ubi->vid_hdr_aloffset); 77 ubi_msg("data offset: %d", ubi->leb_start); 78 ubi_msg("max. allowed volumes: %d", ubi->vtbl_slots); 79 ubi_msg("wear-leveling threshold: %d", CONFIG_MTD_UBI_WL_THRESHOLD); 80 ubi_msg("number of internal volumes: %d", UBI_INT_VOL_COUNT); 81 ubi_msg("number of user volumes: %d", 82 ubi->vol_count - UBI_INT_VOL_COUNT); 83 ubi_msg("available PEBs: %d", ubi->avail_pebs); 84 ubi_msg("total number of reserved PEBs: %d", ubi->rsvd_pebs); 85 ubi_msg("number of PEBs reserved for bad PEB handling: %d", 86 ubi->beb_rsvd_pebs); 87 ubi_msg("max/mean erase counter: %d/%d", ubi->max_ec, ubi->mean_ec); 88 } 89 90 static int ubi_info(int layout) 91 { 92 if (layout) 93 display_volume_info(ubi); 94 else 95 display_ubi_info(ubi); 96 97 return 0; 98 } 99 100 static int ubi_check_volumename(const struct ubi_volume *vol, char *name) 101 { 102 return strcmp(vol->name, name); 103 } 104 105 static int ubi_check(char *name) 106 { 107 int i; 108 109 for (i = 0; i < (ubi->vtbl_slots + 1); i++) { 110 if (!ubi->volumes[i]) 111 continue; /* Empty record */ 112 113 if (!ubi_check_volumename(ubi->volumes[i], name)) 114 return 0; 115 } 116 117 return 1; 118 } 119 120 121 static int verify_mkvol_req(const struct ubi_device *ubi, 122 const struct ubi_mkvol_req *req) 123 { 124 int n, err = EINVAL; 125 126 if (req->bytes < 0 || req->alignment < 0 || req->vol_type < 0 || 127 req->name_len < 0) 128 goto bad; 129 130 if ((req->vol_id < 0 || req->vol_id >= ubi->vtbl_slots) && 131 req->vol_id != UBI_VOL_NUM_AUTO) 132 goto bad; 133 134 if (req->alignment == 0) 135 goto bad; 136 137 if (req->bytes == 0) { 138 printf("No space left in UBI device!\n"); 139 err = ENOMEM; 140 goto bad; 141 } 142 143 if (req->vol_type != UBI_DYNAMIC_VOLUME && 144 req->vol_type != UBI_STATIC_VOLUME) 145 goto bad; 146 147 if (req->alignment > ubi->leb_size) 148 goto bad; 149 150 n = req->alignment % ubi->min_io_size; 151 if (req->alignment != 1 && n) 152 goto bad; 153 154 if (req->name_len > UBI_VOL_NAME_MAX) { 155 printf("Name too long!\n"); 156 err = ENAMETOOLONG; 157 goto bad; 158 } 159 160 return 0; 161 bad: 162 return err; 163 } 164 165 static int ubi_create_vol(char *volume, int64_t size, int dynamic, int vol_id) 166 { 167 struct ubi_mkvol_req req; 168 int err; 169 170 if (dynamic) 171 req.vol_type = UBI_DYNAMIC_VOLUME; 172 else 173 req.vol_type = UBI_STATIC_VOLUME; 174 175 req.vol_id = vol_id; 176 req.alignment = 1; 177 req.bytes = size; 178 179 strcpy(req.name, volume); 180 req.name_len = strlen(volume); 181 req.name[req.name_len] = '\0'; 182 req.padding1 = 0; 183 /* It's duplicated at drivers/mtd/ubi/cdev.c */ 184 err = verify_mkvol_req(ubi, &req); 185 if (err) { 186 printf("verify_mkvol_req failed %d\n", err); 187 return err; 188 } 189 printf("Creating %s volume %s of size %lld\n", 190 dynamic ? "dynamic" : "static", volume, size); 191 /* Call real ubi create volume */ 192 return ubi_create_volume(ubi, &req); 193 } 194 195 static struct ubi_volume *ubi_find_volume(char *volume) 196 { 197 struct ubi_volume *vol = NULL; 198 int i; 199 200 for (i = 0; i < ubi->vtbl_slots; i++) { 201 vol = ubi->volumes[i]; 202 if (vol && !strcmp(vol->name, volume)) 203 return vol; 204 } 205 206 printf("Volume %s not found!\n", volume); 207 return NULL; 208 } 209 210 static int ubi_remove_vol(char *volume) 211 { 212 int err, reserved_pebs, i; 213 struct ubi_volume *vol; 214 215 vol = ubi_find_volume(volume); 216 if (vol == NULL) 217 return ENODEV; 218 219 printf("Remove UBI volume %s (id %d)\n", vol->name, vol->vol_id); 220 221 if (ubi->ro_mode) { 222 printf("It's read-only mode\n"); 223 err = EROFS; 224 goto out_err; 225 } 226 227 err = ubi_change_vtbl_record(ubi, vol->vol_id, NULL); 228 if (err) { 229 printf("Error changing Vol tabel record err=%x\n", err); 230 goto out_err; 231 } 232 reserved_pebs = vol->reserved_pebs; 233 for (i = 0; i < vol->reserved_pebs; i++) { 234 err = ubi_eba_unmap_leb(ubi, vol, i); 235 if (err) 236 goto out_err; 237 } 238 239 kfree(vol->eba_tbl); 240 ubi->volumes[vol->vol_id]->eba_tbl = NULL; 241 ubi->volumes[vol->vol_id] = NULL; 242 243 ubi->rsvd_pebs -= reserved_pebs; 244 ubi->avail_pebs += reserved_pebs; 245 i = ubi->beb_rsvd_level - ubi->beb_rsvd_pebs; 246 if (i > 0) { 247 i = ubi->avail_pebs >= i ? i : ubi->avail_pebs; 248 ubi->avail_pebs -= i; 249 ubi->rsvd_pebs += i; 250 ubi->beb_rsvd_pebs += i; 251 if (i > 0) 252 ubi_msg("reserve more %d PEBs", i); 253 } 254 ubi->vol_count -= 1; 255 256 return 0; 257 out_err: 258 ubi_err(ubi, "cannot remove volume %s, error %d", volume, err); 259 if (err < 0) 260 err = -err; 261 return err; 262 } 263 264 static int ubi_volume_continue_write(char *volume, void *buf, size_t size) 265 { 266 int err = 1; 267 struct ubi_volume *vol; 268 269 vol = ubi_find_volume(volume); 270 if (vol == NULL) 271 return ENODEV; 272 273 err = ubi_more_update_data(ubi, vol, buf, size); 274 if (err < 0) { 275 printf("Couldnt or partially wrote data\n"); 276 return -err; 277 } 278 279 if (err) { 280 size = err; 281 282 err = ubi_check_volume(ubi, vol->vol_id); 283 if (err < 0) 284 return -err; 285 286 if (err) { 287 ubi_warn(ubi, "volume %d on UBI device %d is corrupt", 288 vol->vol_id, ubi->ubi_num); 289 vol->corrupted = 1; 290 } 291 292 vol->checked = 1; 293 ubi_gluebi_updated(vol); 294 } 295 296 return 0; 297 } 298 299 int ubi_volume_begin_write(char *volume, void *buf, size_t size, 300 size_t full_size) 301 { 302 int err = 1; 303 int rsvd_bytes = 0; 304 struct ubi_volume *vol; 305 306 vol = ubi_find_volume(volume); 307 if (vol == NULL) 308 return ENODEV; 309 310 rsvd_bytes = vol->reserved_pebs * (ubi->leb_size - vol->data_pad); 311 if (size < 0 || size > rsvd_bytes) { 312 printf("size > volume size! Aborting!\n"); 313 return EINVAL; 314 } 315 316 err = ubi_start_update(ubi, vol, full_size); 317 if (err < 0) { 318 printf("Cannot start volume update\n"); 319 return -err; 320 } 321 322 return ubi_volume_continue_write(volume, buf, size); 323 } 324 325 int ubi_volume_write(char *volume, void *buf, size_t size) 326 { 327 return ubi_volume_begin_write(volume, buf, size, size); 328 } 329 330 int ubi_volume_read(char *volume, char *buf, size_t size) 331 { 332 int err, lnum, off, len, tbuf_size; 333 void *tbuf; 334 unsigned long long tmp; 335 struct ubi_volume *vol; 336 loff_t offp = 0; 337 338 vol = ubi_find_volume(volume); 339 if (vol == NULL) 340 return ENODEV; 341 342 if (vol->updating) { 343 printf("updating"); 344 return EBUSY; 345 } 346 if (vol->upd_marker) { 347 printf("damaged volume, update marker is set"); 348 return EBADF; 349 } 350 if (offp == vol->used_bytes) 351 return 0; 352 353 if (size == 0) { 354 printf("No size specified -> Using max size (%lld)\n", vol->used_bytes); 355 size = vol->used_bytes; 356 } 357 358 if (vol->corrupted) 359 printf("read from corrupted volume %d", vol->vol_id); 360 if (offp + size > vol->used_bytes) 361 size = vol->used_bytes - offp; 362 363 tbuf_size = vol->usable_leb_size; 364 if (size < tbuf_size) 365 tbuf_size = ALIGN(size, ubi->min_io_size); 366 tbuf = malloc_cache_aligned(tbuf_size); 367 if (!tbuf) { 368 printf("NO MEM\n"); 369 return ENOMEM; 370 } 371 len = size > tbuf_size ? tbuf_size : size; 372 373 tmp = offp; 374 off = do_div(tmp, vol->usable_leb_size); 375 lnum = tmp; 376 do { 377 if (off + len >= vol->usable_leb_size) 378 len = vol->usable_leb_size - off; 379 380 err = ubi_eba_read_leb(ubi, vol, lnum, tbuf, off, len, 0); 381 if (err) { 382 printf("read err %x\n", err); 383 err = -err; 384 break; 385 } 386 off += len; 387 if (off == vol->usable_leb_size) { 388 lnum += 1; 389 off -= vol->usable_leb_size; 390 } 391 392 size -= len; 393 offp += len; 394 395 memcpy(buf, tbuf, len); 396 397 buf += len; 398 len = size > tbuf_size ? tbuf_size : size; 399 } while (size); 400 401 free(tbuf); 402 return err; 403 } 404 405 static int ubi_dev_scan(struct mtd_info *info, char *ubidev, 406 const char *vid_header_offset) 407 { 408 struct mtd_device *dev; 409 struct part_info *part; 410 struct mtd_partition mtd_part; 411 char ubi_mtd_param_buffer[80]; 412 u8 pnum; 413 int err; 414 415 if (find_dev_and_part(ubidev, &dev, &pnum, &part) != 0) 416 return 1; 417 418 sprintf(buffer, "mtd=%d", pnum); 419 memset(&mtd_part, 0, sizeof(mtd_part)); 420 mtd_part.name = buffer; 421 mtd_part.size = part->size; 422 mtd_part.offset = part->offset; 423 add_mtd_partitions(info, &mtd_part, 1); 424 425 strcpy(ubi_mtd_param_buffer, buffer); 426 if (vid_header_offset) 427 sprintf(ubi_mtd_param_buffer, "mtd=%d,%s", pnum, 428 vid_header_offset); 429 err = ubi_mtd_param_parse(ubi_mtd_param_buffer, NULL); 430 if (err) { 431 del_mtd_partitions(info); 432 return -err; 433 } 434 435 err = ubi_init(); 436 if (err) { 437 del_mtd_partitions(info); 438 return -err; 439 } 440 441 ubi_initialized = 1; 442 443 return 0; 444 } 445 446 int ubi_detach(void) 447 { 448 if (mtdparts_init() != 0) { 449 printf("Error initializing mtdparts!\n"); 450 return 1; 451 } 452 453 #ifdef CONFIG_CMD_UBIFS 454 /* 455 * Automatically unmount UBIFS partition when user 456 * changes the UBI device. Otherwise the following 457 * UBIFS commands will crash. 458 */ 459 if (ubifs_is_mounted()) 460 cmd_ubifs_umount(); 461 #endif 462 463 /* 464 * Call ubi_exit() before re-initializing the UBI subsystem 465 */ 466 if (ubi_initialized) { 467 ubi_exit(); 468 del_mtd_partitions(ubi_dev.mtd_info); 469 ubi_initialized = 0; 470 } 471 472 ubi_dev.selected = 0; 473 return 0; 474 } 475 476 int ubi_part(char *part_name, const char *vid_header_offset) 477 { 478 int err = 0; 479 char mtd_dev[16]; 480 struct mtd_device *dev; 481 struct part_info *part; 482 u8 pnum; 483 484 ubi_detach(); 485 /* 486 * Search the mtd device number where this partition 487 * is located 488 */ 489 if (find_dev_and_part(part_name, &dev, &pnum, &part)) { 490 printf("Partition %s not found!\n", part_name); 491 return 1; 492 } 493 sprintf(mtd_dev, "%s%d", MTD_DEV_TYPE(dev->id->type), dev->id->num); 494 ubi_dev.mtd_info = get_mtd_device_nm(mtd_dev); 495 if (IS_ERR(ubi_dev.mtd_info)) { 496 printf("Partition %s not found on device %s!\n", part_name, 497 mtd_dev); 498 return 1; 499 } 500 501 ubi_dev.selected = 1; 502 503 strcpy(ubi_dev.part_name, part_name); 504 err = ubi_dev_scan(ubi_dev.mtd_info, ubi_dev.part_name, 505 vid_header_offset); 506 if (err) { 507 printf("UBI init error %d\n", err); 508 ubi_dev.selected = 0; 509 return err; 510 } 511 512 ubi = ubi_devices[0]; 513 514 return 0; 515 } 516 517 static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 518 { 519 int64_t size = 0; 520 ulong addr = 0; 521 522 if (argc < 2) 523 return CMD_RET_USAGE; 524 525 526 if (strcmp(argv[1], "detach") == 0) { 527 if (argc < 2) 528 return CMD_RET_USAGE; 529 530 return ubi_detach(); 531 } 532 533 534 if (strcmp(argv[1], "part") == 0) { 535 const char *vid_header_offset = NULL; 536 537 /* Print current partition */ 538 if (argc == 2) { 539 if (!ubi_dev.selected) { 540 printf("Error, no UBI device/partition selected!\n"); 541 return 1; 542 } 543 544 printf("Device %d: %s, partition %s\n", 545 ubi_dev.nr, ubi_dev.mtd_info->name, ubi_dev.part_name); 546 return 0; 547 } 548 549 if (argc < 3) 550 return CMD_RET_USAGE; 551 552 if (argc > 3) 553 vid_header_offset = argv[3]; 554 555 return ubi_part(argv[2], vid_header_offset); 556 } 557 558 if ((strcmp(argv[1], "part") != 0) && (!ubi_dev.selected)) { 559 printf("Error, no UBI device/partition selected!\n"); 560 return 1; 561 } 562 563 if (strcmp(argv[1], "info") == 0) { 564 int layout = 0; 565 if (argc > 2 && !strncmp(argv[2], "l", 1)) 566 layout = 1; 567 return ubi_info(layout); 568 } 569 570 if (strcmp(argv[1], "check") == 0) { 571 if (argc > 2) 572 return ubi_check(argv[2]); 573 574 printf("Error, no volume name passed\n"); 575 return 1; 576 } 577 578 if (strncmp(argv[1], "create", 6) == 0) { 579 int dynamic = 1; /* default: dynamic volume */ 580 int id = UBI_VOL_NUM_AUTO; 581 582 /* Use maximum available size */ 583 size = 0; 584 585 /* E.g., create volume size type vol_id */ 586 if (argc == 6) { 587 id = simple_strtoull(argv[5], NULL, 16); 588 argc--; 589 } 590 591 /* E.g., create volume size type */ 592 if (argc == 5) { 593 if (strncmp(argv[4], "s", 1) == 0) 594 dynamic = 0; 595 else if (strncmp(argv[4], "d", 1) != 0) { 596 printf("Incorrect type\n"); 597 return 1; 598 } 599 argc--; 600 } 601 /* E.g., create volume size */ 602 if (argc == 4) { 603 if (argv[3][0] != '-') 604 size = simple_strtoull(argv[3], NULL, 16); 605 argc--; 606 } 607 /* Use maximum available size */ 608 if (!size) { 609 size = (int64_t)ubi->avail_pebs * ubi->leb_size; 610 printf("No size specified -> Using max size (%lld)\n", size); 611 } 612 /* E.g., create volume */ 613 if (argc == 3) 614 return ubi_create_vol(argv[2], size, dynamic, id); 615 } 616 617 if (strncmp(argv[1], "remove", 6) == 0) { 618 /* E.g., remove volume */ 619 if (argc == 3) 620 return ubi_remove_vol(argv[2]); 621 } 622 623 if (strncmp(argv[1], "write", 5) == 0) { 624 int ret; 625 626 if (argc < 5) { 627 printf("Please see usage\n"); 628 return 1; 629 } 630 631 addr = simple_strtoul(argv[2], NULL, 16); 632 size = simple_strtoul(argv[4], NULL, 16); 633 634 if (strlen(argv[1]) == 10 && 635 strncmp(argv[1] + 5, ".part", 5) == 0) { 636 if (argc < 6) { 637 ret = ubi_volume_continue_write(argv[3], 638 (void *)addr, size); 639 } else { 640 size_t full_size; 641 full_size = simple_strtoul(argv[5], NULL, 16); 642 ret = ubi_volume_begin_write(argv[3], 643 (void *)addr, size, full_size); 644 } 645 } else { 646 ret = ubi_volume_write(argv[3], (void *)addr, size); 647 } 648 if (!ret) { 649 printf("%lld bytes written to volume %s\n", size, 650 argv[3]); 651 } 652 653 return ret; 654 } 655 656 if (strncmp(argv[1], "read", 4) == 0) { 657 size = 0; 658 659 /* E.g., read volume size */ 660 if (argc == 5) { 661 size = simple_strtoul(argv[4], NULL, 16); 662 argc--; 663 } 664 665 /* E.g., read volume */ 666 if (argc == 4) { 667 addr = simple_strtoul(argv[2], NULL, 16); 668 argc--; 669 } 670 671 if (argc == 3) { 672 printf("Read %lld bytes from volume %s to %lx\n", size, 673 argv[3], addr); 674 675 return ubi_volume_read(argv[3], (char *)addr, size); 676 } 677 } 678 679 printf("Please see usage\n"); 680 return 1; 681 } 682 683 U_BOOT_CMD( 684 ubi, 6, 1, do_ubi, 685 "ubi commands", 686 "detach" 687 " - detach ubi from a mtd partition\n" 688 "ubi part [part] [offset]\n" 689 " - Show or set current partition (with optional VID" 690 " header offset)\n" 691 "ubi info [l[ayout]]" 692 " - Display volume and ubi layout information\n" 693 "ubi check volumename" 694 " - check if volumename exists\n" 695 "ubi create[vol] volume [size] [type] [id]\n" 696 " - create volume name with size ('-' for maximum" 697 " available size)\n" 698 "ubi write[vol] address volume size" 699 " - Write volume from address with size\n" 700 "ubi write.part address volume size [fullsize]\n" 701 " - Write part of a volume from address\n" 702 "ubi read[vol] address volume [size]" 703 " - Read volume to address with size\n" 704 "ubi remove[vol] volume" 705 " - Remove volume\n" 706 "[Legends]\n" 707 " volume: character name\n" 708 " size: specified in bytes\n" 709 " type: s[tatic] or d[ynamic] (default=dynamic)" 710 ); 711