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