UBI command support v3
PATCH 1/1 UBI command support v3
It supports basic operation such as create, remove, read, and write.
---
common/Makefile +1 -0
@@ -139,6 +139,7 @@ COBJS-$(CONFIG_CMD_SETEXPR) += cmd_setexpr.o COBJS-$(CONFIG_CMD_SPI) += cmd_spi.o COBJS-$(CONFIG_CMD_STRINGS) += cmd_strings.o COBJS-$(CONFIG_CMD_TERMINAL) += cmd_terminal.o +COBJS-$(CONFIG_CMD_UBI) += cmd_ubi.o COBJS-$(CONFIG_CMD_UNIVERSE) += cmd_universe.o ifdef CONFIG_CMD_USB COBJS-y += cmd_usb.o
common/cmd_ubi.c new file +515 -0
515 lines not on this page · raw message
include/exports.h +1 -0
@@ -25,6 +25,7 @@ char *getenv (char *name);int setenv (char *varname,char *varvalue);long simple_strtol (const char *cp,char **endp,unsigned int base);int strcmp (const char * cs,const char * ct); +int ustrtoul (const char *cp,char **endp,unsigned int base);#ifdef CONFIG_HAS_UID void forceenv (char *varname,char *varvalue);#endif
include/jffs2/load_kernel.h +5 -0
@@ -73,4 +73,9 @@ struct mtdids {#define putLabeledWord (x, y) printf("%s %08x\n", x, (unsigned int)y)#define led_blink (x, y, z, a) +/* common/cmd_jffs2.c */ +extern int mtdparts_init (void ); +extern int find_dev_and_part (const char *id,struct mtd_device **dev, +u8 *part_num,struct part_info **part); +#endif /* load_kernel_h */
lib_generic/vsprintf.c +23 -0
@@ -55,6 +55,29 @@ long simple_strtol(const char *cp,char **endp,unsigned int base)return simple_strtoul (cp,endp,base); } +int ustrtoul (const char *cp,char **endp,unsigned int base) +{ +unsigned long result =simple_strtoul (cp, endp, base); +switch (**endp) { +case 'G' : + result *=1024 ; +/* fall through */ +case 'M' : + result *=1024 ; +/* fall through */ +case 'K' : +case 'k' : + result *=1024 ; +if ((*endp)[1 ] =='i' ) { +if ((*endp)[2 ] =='B' ) + (*endp) +=3 ; +else + (*endp) +=2 ; + } + } +return result; +} +#ifdef CONFIG_SYS_64BIT_STRTOUL unsigned long long simple_strtoull (const char *cp,char **endp,unsigned int base) {
PATCH 1/1 UBI command support v3
2008/10/28 Kyungmin Park <[email protected]>:
Quoted 3 lines
It supports basic operation such as create, remove, read, and write.
Signed-off-by Kyungmin Park <[email protected]>
Would it be possible to have the U-boot environment in the part of the flash managed by UBI? I suppose it involves creating a U-Boot Environment volume in UBI and then using ubi function to read/update that volume.
Regards, Magnus
PATCH 1/1 UBI command support v3
Hi,
Quoted 9 lines · Magnus Lilja
2008/10/28 Kyungmin Park <[email protected]>:
Quoted 3 lines
It supports basic operation such as create, remove, read, and write.
Signed-off-by Kyungmin Park <[email protected]>Would it be possible to have the U-boot environment in the part of the flash managed by UBI? I suppose it involves creating a U-Boot Environment volume in UBI and then using ubi function to read/update that volume.
Principally yes. But not yet used
This implementation only used kernel side UBI, rootfs, user data area. However the UBI supports multiple UBI devices. It cant combine several UBI device such as params UBI, kernel UBI, and rootfs UBI. Of course it depends on your configurations
I will list the TODO list this one.
Thank you,
Kyungmin Park
PATCH 1/1 UBI command support v3
In reply to Kyungmin ParkDear Kyungmin Park,
Some more comments.
2008/10/28 Kyungmin Park <[email protected]>:
Quoted 80 lines
It supports basic operation such as create, remove, read, and write.
Signed-off-by Kyungmin Park <[email protected]>---
common/cmd_ubi.c new file +71
-0+static int ubi_volume_read (char *volume,char *buf,size_t size) +{ +int err, lnum, off, len, tbuf_size, i =0 ; +size_t count_save = size; +void *tbuf; +unsigned long long tmp; +struct ubi_volume *vol =NULL ; +loff_t offp =0 ; + +for (i =0 ; i < ubi->vtbl_slots; i++) { + vol = ubi->volumes[i]; +if (vol && !strcmp (vol->name, volume)) { +printf ("Volume %s found at volume id %d\n" , + volume, vol->vol_id); +break ; + } + } +if (i == ubi->vtbl_slots) { +printf ("%s voume not found\n" , volume); +return 0 ; + } + +printf ("read %i bytes from volume %d to %x(buf address)\n" , + (int ) size, vol->vol_id, (unsigned )buf); + +if (vol->updating) { +printf ("updating" ); +return -EBUSY ; + } +if (vol->upd_marker) { +printf ("damaged volume, update marker is set" ); +return -EBADF ; + } +if (offp == vol->used_bytes) +return 0 ; + +if (size ==0 ) { +printf ("Read [%lu] bytes\n" , (unsigned long ) vol->used_bytes); + size = vol->used_bytes; + } + +if (vol->corrupted) +printf ("read from corrupted volume %d" , vol->vol_id); +if (offp + size > vol->used_bytes) + count_save = size = vol->used_bytes - offp; + + tbuf_size = vol->usable_leb_size; +if (size < tbuf_size) + tbuf_size =ALIGN (size, ubi->min_io_size); + tbuf =malloc (tbuf_size); +if (!tbuf) { +printf ("NO MEM\n" ); +return -ENOMEM ; + } + len = size > tbuf_size ? tbuf_size : size; + + tmp = offp; + off =do_div (tmp, vol->usable_leb_size); + lnum = tmp; +printf ("off=%d lnum=%d\n" , off, lnum); + do { + if (off + len >= vol->usable_leb_size) + len = vol->usable_leb_size - off; + + err = ubi_eba_read_leb(ubi, vol, lnum, tbuf, off, len, 0); + if (err) { + printf("read err %x\n", err); + break; + } + off += len; + if (off == vol->usable_leb_size) {
common/cmd_ubi.c line 384
Quoted 10 lines
common/cmd_ubi.c new file +10
-0+ lnum +=1 ; + off -= vol->usable_leb_size; + } + + size -= len; + offp += len; + +printf ("buf = %x\n" , (unsigned )buf); +memcpy (buf, tbuf, len); +printf ("buf[0] = %x\n" , buf[0 ]);
The printf()'s before and after memcpy() looks like stuff used during development of this file and they should be removed.
Quoted 98 lines
common/cmd_ubi.c new file +98
-0+ + buf += len; + len = size > tbuf_size ? tbuf_size : size; + }while (size); + +free (tbuf); +return err ? err : count_save - size; +} + +static int do_ubi (cmd_tbl_t *cmdtp,int flag,int argc,char *argv[]) +{ +size_t size =0 ; +ulong addr =0 ; +int err =0 ; + +if (!ubi_initialized) { + err =ubi_board_scan (); +if (err) { +printf ("UBI init error %d\n" , err); +return err; + } + ubi = ubi_devices[0 ]; + ubi_initialized =1 ; + } + +if (argc <2 ) { +printf ("Usage:\n%s\n" , cmdtp->usage); +return 1 ; + } +if (strcmp (argv[1 ],"info" ) ==0 ) { +int layout =0 ; +if (argc >2 && !strncmp (argv[2 ],"l" ,1 )) + layout =1 ; +return ubi_info (layout); + } +if (strncmp (argv[1 ],"create" ,6 ) ==0 ) { +int dynamic =1 ;/* default: dynamic volume */ + +/* Use maximum available size */ + size =0 ; + +/* E.g., create volume size type */ +if (argc ==5 ) { +if (strncmp (argv[4 ],"s" ,1 ) ==0 ) + dynamic =0 ; +else if (strncmp (argv[4 ],"d" ,1 ) !=0 ) { +printf ("Incorrect type\n" ); +return 1 ; + } + argc--; + } +/* E.g., create volume size */ +if (argc ==4 ) { + err =parse_num (&size, argv[3 ]); +if (err) { +printf ("Incorrect type\n" ); +return err; + } + argc--; + } +/* Use maximum available size */ +if (!size) + size = ubi->avail_pebs * ubi->leb_size; +/* E.g., create volume */ +if (argc ==3 ) +return ubi_create_vol (argv[2 ], size, dynamic); + } +if (strncmp (argv[1 ],"remove" ,6 ) ==0 ) { +/* E.g., remove volume */ +if (argc ==3 ) +return ubi_remove_vol (argv[2 ]); + } +if (strncmp (argv[1 ],"write" ,5 ) ==0 ) { +if (argc <5 ) { +printf ("Please see usage\n" ); +return 1 ; + } + + addr =simple_strtoul (argv[2 ],NULL ,16 ); + err =parse_num (&size, argv[4 ]); +if (err) { +printf ("Please see usage\n" ); +return err; + } + +return ubi_volume_write (argv[3 ], (void *)addr, size); + } +if (strncmp (argv[1 ],"read" ,4 ) ==0 ) { + size =0 ; + +/* E.g., read volume size */ +if (argc ==5 ) { + err =parse_num (&size, argv[4 ]); +if (err) { +printf ("Please see usage\n" ); +return err; + } + argc--;
common/cmd_ubi.c line 492
Quoted 10 lines
common/cmd_ubi.c new file +10
-0+ } + +/* E.g., read volume */ +if (argc ==4 ) { + addr =simple_strtoul (argv[2 ],NULL ,16 ); + argc--; + } + +if (argc ==3 ) +return ubi_volume_read (argv[3 ], (char *)addr, size);
It seems to me that ubi_volume_read() can return 0 when there is an error, so it may not be correct to use that return value here. AFAIK do_ubi()-like functions return 0 upon success and non-zero otherwise.
Regards, Magnus
PATCH 1/1 UBI command support v3
Quoted 90 lines · Magnus Lilja
Dear Kyungmin Park,
Some more comments.
2008/10/28 Kyungmin Park <[email protected]>:
Quoted 85 lines
It supports basic operation such as create, remove, read, and write.
Signed-off-by Kyungmin Park <[email protected]>---
common/cmd_ubi.c new file +76
-0+static int ubi_volume_read (char *volume,char *buf,size_t size) +{ +int err, lnum, off, len, tbuf_size, i =0 ; +size_t count_save = size; +void *tbuf; +unsigned long long tmp; +struct ubi_volume *vol =NULL ; +loff_t offp =0 ; + +for (i =0 ; i < ubi->vtbl_slots; i++) { + vol = ubi->volumes[i]; +if (vol && !strcmp (vol->name, volume)) { +printf ("Volume %s found at volume id %d\n" , + volume, vol->vol_id); +break ; + } + } +if (i == ubi->vtbl_slots) { +printf ("%s voume not found\n" , volume); +return 0 ; + } + +printf ("read %i bytes from volume %d to %x(buf address)\n" , + (int ) size, vol->vol_id, (unsigned )buf); + +if (vol->updating) { +printf ("updating" ); +return -EBUSY ; + } +if (vol->upd_marker) { +printf ("damaged volume, update marker is set" ); +return -EBADF ; + } +if (offp == vol->used_bytes) +return 0 ; + +if (size ==0 ) { +printf ("Read [%lu] bytes\n" , (unsigned long ) vol->used_bytes); + size = vol->used_bytes; + } + +if (vol->corrupted) +printf ("read from corrupted volume %d" , vol->vol_id); +if (offp + size > vol->used_bytes) + count_save = size = vol->used_bytes - offp; + + tbuf_size = vol->usable_leb_size; +if (size < tbuf_size) + tbuf_size =ALIGN (size, ubi->min_io_size); + tbuf =malloc (tbuf_size); +if (!tbuf) { +printf ("NO MEM\n" ); +return -ENOMEM ; + } + len = size > tbuf_size ? tbuf_size : size; + + tmp = offp; + off =do_div (tmp, vol->usable_leb_size); + lnum = tmp; +printf ("off=%d lnum=%d\n" , off, lnum); + do { + if (off + len >= vol->usable_leb_size) + len = vol->usable_leb_size - off; + + err = ubi_eba_read_leb(ubi, vol, lnum, tbuf, off, len, 0); + if (err) { + printf("read err %x\n", err); + break; + } + off += len; + if (off == vol->usable_leb_size) { + lnum += 1; + off -= vol->usable_leb_size; + } + + size -= len;
Quoted 8 lines
common/cmd_ubi.c line 384
Quoted 5 lines
common/cmd_ubi.c new file +5
-0+ offp += len; + +printf ("buf = %x\n" , (unsigned )buf); +memcpy (buf, tbuf, len); +printf ("buf[0] = %x\n" , buf[0 ]);The printf()'s before and after
memcpy()looks like stuff used during development of this file and they should be removed.
Yes, correct, I'll remove it
Quoted 104 lines
Quoted 104 lines
common/cmd_ubi.c new file +103
-0+ + buf += len; + len = size > tbuf_size ? tbuf_size : size; + }while (size); + +free (tbuf); +return err ? err : count_save - size; +} + +static int do_ubi (cmd_tbl_t *cmdtp,int flag,int argc,char *argv[]) +{ +size_t size =0 ; +ulong addr =0 ; +int err =0 ; + +if (!ubi_initialized) { + err =ubi_board_scan (); +if (err) { +printf ("UBI init error %d\n" , err); +return err; + } + ubi = ubi_devices[0 ]; + ubi_initialized =1 ; + } + +if (argc <2 ) { +printf ("Usage:\n%s\n" , cmdtp->usage); +return 1 ; + } +if (strcmp (argv[1 ],"info" ) ==0 ) { +int layout =0 ; +if (argc >2 && !strncmp (argv[2 ],"l" ,1 )) + layout =1 ; +return ubi_info (layout); + } +if (strncmp (argv[1 ],"create" ,6 ) ==0 ) { +int dynamic =1 ;/* default: dynamic volume */ + +/* Use maximum available size */ + size =0 ; + +/* E.g., create volume size type */ +if (argc ==5 ) { +if (strncmp (argv[4 ],"s" ,1 ) ==0 ) + dynamic =0 ; +else if (strncmp (argv[4 ],"d" ,1 ) !=0 ) { +printf ("Incorrect type\n" ); +return 1 ; + } + argc--; + } +/* E.g., create volume size */ +if (argc ==4 ) { + err =parse_num (&size, argv[3 ]); +if (err) { +printf ("Incorrect type\n" ); +return err; + } + argc--; + } +/* Use maximum available size */ +if (!size) + size = ubi->avail_pebs * ubi->leb_size; +/* E.g., create volume */ +if (argc ==3 ) +return ubi_create_vol (argv[2 ], size, dynamic); + } +if (strncmp (argv[1 ],"remove" ,6 ) ==0 ) { +/* E.g., remove volume */ +if (argc ==3 ) +return ubi_remove_vol (argv[2 ]); + } +if (strncmp (argv[1 ],"write" ,5 ) ==0 ) { +if (argc <5 ) { +printf ("Please see usage\n" ); +return 1 ; + } + + addr =simple_strtoul (argv[2 ],NULL ,16 ); + err =parse_num (&size, argv[4 ]); +if (err) { +printf ("Please see usage\n" ); +return err; + } + +return ubi_volume_write (argv[3 ], (void *)addr, size); + } +if (strncmp (argv[1 ],"read" ,4 ) ==0 ) { + size =0 ; + +/* E.g., read volume size */ +if (argc ==5 ) { + err =parse_num (&size, argv[4 ]); +if (err) { +printf ("Please see usage\n" ); +return err; + } + argc--; + } + +/* E.g., read volume */ +if (argc ==4 ) { + addr =simple_strtoul (argv[2 ],NULL ,16 );
Quoted 8 lines
common/cmd_ubi.c line 492
Quoted 5 lines
common/cmd_ubi.c new file +5
-0+ argc--; + } + +if (argc ==3 ) +return ubi_volume_read (argv[3 ], (char *)addr, size);It seems to me that
ubi_volume_read()can return 0 when there is an error, so it may not be correct to use that return value here. AFAIK
Really? I will check the return value.
Quoted 1 line
do_ubi()-like functions return 0 upon success and non-zero otherwise.
Agreed
Thank you,
Kyungmin Park