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