cmd_ext_common.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. /*
  2. * (C) Copyright 2011 - 2012 Samsung Electronics
  3. * EXT2/4 filesystem implementation in Uboot by
  4. * Uma Shankar <uma.shankar@samsung.com>
  5. * Manjunatha C Achar <a.manjunatha@samsung.com>
  6. *
  7. * Ext4fs support
  8. * made from existing cmd_ext2.c file of Uboot
  9. *
  10. * (C) Copyright 2004
  11. * esd gmbh <www.esd-electronics.com>
  12. * Reinhard Arlt <reinhard.arlt@esd-electronics.com>
  13. *
  14. * made from cmd_reiserfs by
  15. *
  16. * (C) Copyright 2003 - 2004
  17. * Sysgo Real-Time Solutions, AG <www.elinos.com>
  18. * Pavel Bartusek <pba@sysgo.com>
  19. *
  20. * This program is free software; you can redistribute it and/or
  21. * modify it under the terms of the GNU General Public License as
  22. * published by the Free Software Foundation; either version 2 of
  23. * the License, or (at your option) any later version.
  24. *
  25. * This program is distributed in the hope that it will be useful,
  26. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  27. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  28. * GNU General Public License for more details.
  29. *
  30. * You should have received a copy of the GNU General Public License
  31. * along with this program; if not, write to the Free Software
  32. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  33. * MA 02111-1307 USA
  34. *
  35. */
  36. /*
  37. * Changelog:
  38. * 0.1 - Newly created file for ext4fs support. Taken from cmd_ext2.c
  39. * file in uboot. Added ext4fs ls load and write support.
  40. */
  41. #include <common.h>
  42. #include <part.h>
  43. #include <config.h>
  44. #include <command.h>
  45. #include <image.h>
  46. #include <linux/ctype.h>
  47. #include <asm/byteorder.h>
  48. #include <ext_common.h>
  49. #include <ext4fs.h>
  50. #include <linux/stat.h>
  51. #include <malloc.h>
  52. #if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
  53. #include <usb.h>
  54. #endif
  55. #if !defined(CONFIG_DOS_PARTITION) && !defined(CONFIG_EFI_PARTITION)
  56. #error DOS or EFI partition support must be selected
  57. #endif
  58. #define DOS_PART_MAGIC_OFFSET 0x1fe
  59. #define DOS_FS_TYPE_OFFSET 0x36
  60. #define DOS_FS32_TYPE_OFFSET 0x52
  61. int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc,
  62. char *const argv[])
  63. {
  64. char *filename = NULL;
  65. char *ep;
  66. int dev;
  67. unsigned long part = 1;
  68. ulong addr = 0;
  69. ulong part_length;
  70. int filelen;
  71. disk_partition_t info;
  72. struct ext_filesystem *fs;
  73. char buf[12];
  74. unsigned long count;
  75. const char *addr_str;
  76. count = 0;
  77. addr = simple_strtoul(argv[3], NULL, 16);
  78. filename = getenv("bootfile");
  79. switch (argc) {
  80. case 3:
  81. addr_str = getenv("loadaddr");
  82. if (addr_str != NULL)
  83. addr = simple_strtoul(addr_str, NULL, 16);
  84. else
  85. addr = CONFIG_SYS_LOAD_ADDR;
  86. break;
  87. case 4:
  88. break;
  89. case 5:
  90. filename = argv[4];
  91. break;
  92. case 6:
  93. filename = argv[4];
  94. count = simple_strtoul(argv[5], NULL, 16);
  95. break;
  96. default:
  97. return cmd_usage(cmdtp);
  98. }
  99. if (!filename) {
  100. puts("** No boot file defined **\n");
  101. return 1;
  102. }
  103. dev = (int)simple_strtoul(argv[2], &ep, 16);
  104. ext4_dev_desc = get_dev(argv[1], dev);
  105. if (ext4_dev_desc == NULL) {
  106. printf("** Block device %s %d not supported\n", argv[1], dev);
  107. return 1;
  108. }
  109. if (init_fs(ext4_dev_desc))
  110. return 1;
  111. fs = get_fs();
  112. if (*ep) {
  113. if (*ep != ':') {
  114. puts("** Invalid boot device, use `dev[:part]' **\n");
  115. goto fail;
  116. }
  117. part = simple_strtoul(++ep, NULL, 16);
  118. }
  119. if (part != 0) {
  120. if (get_partition_info(fs->dev_desc, part, &info)) {
  121. printf("** Bad partition %lu **\n", part);
  122. goto fail;
  123. }
  124. if (strncmp((char *)info.type, BOOT_PART_TYPE,
  125. strlen(BOOT_PART_TYPE)) != 0) {
  126. printf("** Invalid partition type \"%s\""
  127. " (expect \"" BOOT_PART_TYPE "\")\n", info.type);
  128. goto fail;
  129. }
  130. printf("Loading file \"%s\" "
  131. "from %s device %d:%lu %s\n",
  132. filename, argv[1], dev, part, info.name);
  133. } else {
  134. printf("Loading file \"%s\" from %s device %d\n",
  135. filename, argv[1], dev);
  136. }
  137. part_length = ext4fs_set_blk_dev(fs->dev_desc, part);
  138. if (part_length == 0) {
  139. printf("**Bad partition - %s %d:%lu **\n", argv[1], dev, part);
  140. ext4fs_close();
  141. goto fail;
  142. }
  143. if (!ext4fs_mount(part_length)) {
  144. printf("** Bad ext2 partition or disk - %s %d:%lu **\n",
  145. argv[1], dev, part);
  146. ext4fs_close();
  147. goto fail;
  148. }
  149. filelen = ext4fs_open(filename);
  150. if (filelen < 0) {
  151. printf("** File not found %s\n", filename);
  152. ext4fs_close();
  153. goto fail;
  154. }
  155. if ((count < filelen) && (count != 0))
  156. filelen = count;
  157. if (ext4fs_read((char *)addr, filelen) != filelen) {
  158. printf("** Unable to read \"%s\" from %s %d:%lu **\n",
  159. filename, argv[1], dev, part);
  160. ext4fs_close();
  161. goto fail;
  162. }
  163. ext4fs_close();
  164. deinit_fs(fs->dev_desc);
  165. /* Loading ok, update default load address */
  166. load_addr = addr;
  167. printf("%d bytes read\n", filelen);
  168. sprintf(buf, "%X", filelen);
  169. setenv("filesize", buf);
  170. return 0;
  171. fail:
  172. deinit_fs(fs->dev_desc);
  173. return 1;
  174. }
  175. int do_ext_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
  176. {
  177. const char *filename = "/";
  178. int dev;
  179. unsigned long part = 1;
  180. char *ep;
  181. struct ext_filesystem *fs;
  182. int part_length;
  183. if (argc < 3)
  184. return cmd_usage(cmdtp);
  185. dev = (int)simple_strtoul(argv[2], &ep, 16);
  186. ext4_dev_desc = get_dev(argv[1], dev);
  187. if (ext4_dev_desc == NULL) {
  188. printf("\n** Block device %s %d not supported\n", argv[1], dev);
  189. return 1;
  190. }
  191. if (init_fs(ext4_dev_desc))
  192. return 1;
  193. fs = get_fs();
  194. if (*ep) {
  195. if (*ep != ':') {
  196. puts("\n** Invalid boot device, use `dev[:part]' **\n");
  197. goto fail;
  198. }
  199. part = simple_strtoul(++ep, NULL, 16);
  200. }
  201. if (argc == 4)
  202. filename = argv[3];
  203. part_length = ext4fs_set_blk_dev(fs->dev_desc, part);
  204. if (part_length == 0) {
  205. printf("** Bad partition - %s %d:%lu **\n", argv[1], dev, part);
  206. ext4fs_close();
  207. goto fail;
  208. }
  209. if (!ext4fs_mount(part_length)) {
  210. printf("** Bad ext2 partition or disk - %s %d:%lu **\n",
  211. argv[1], dev, part);
  212. ext4fs_close();
  213. goto fail;
  214. }
  215. if (ext4fs_ls(filename)) {
  216. printf("** Error extfs_ls() **\n");
  217. ext4fs_close();
  218. goto fail;
  219. };
  220. ext4fs_close();
  221. deinit_fs(fs->dev_desc);
  222. return 0;
  223. fail:
  224. deinit_fs(fs->dev_desc);
  225. return 1;
  226. }