blob: 56ee9a55b0f625ceffb2743baadd7e5802d9a49b [file] [log] [blame]
Uma Shankara1596432012-05-25 21:21:44 +05301/*
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/*
38 * Changelog:
39 * 0.1 - Newly created file for ext4fs support. Taken from cmd_ext2.c
40 * file in uboot. Added ext4fs ls load and write support.
41 */
42
43#include <common.h>
44#include <part.h>
45#include <config.h>
46#include <command.h>
47#include <image.h>
48#include <linux/ctype.h>
49#include <asm/byteorder.h>
50#include <ext_common.h>
51#include <ext4fs.h>
52#include <linux/stat.h>
53#include <malloc.h>
54
55#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
56#include <usb.h>
57#endif
58
59#if !defined(CONFIG_DOS_PARTITION) && !defined(CONFIG_EFI_PARTITION)
60#error DOS or EFI partition support must be selected
61#endif
62
63#define DOS_PART_MAGIC_OFFSET 0x1fe
64#define DOS_FS_TYPE_OFFSET 0x36
65#define DOS_FS32_TYPE_OFFSET 0x52
66
67int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc,
68 char *const argv[])
69{
70 char *filename = NULL;
71 char *ep;
72 int dev;
73 unsigned long part = 1;
74 ulong addr = 0;
75 ulong part_length;
76 int filelen;
77 disk_partition_t info;
78 struct ext_filesystem *fs;
79 char buf[12];
80 unsigned long count;
81 const char *addr_str;
82
83 count = 0;
84 addr = simple_strtoul(argv[3], NULL, 16);
85 filename = getenv("bootfile");
86 switch (argc) {
87 case 3:
88 addr_str = getenv("loadaddr");
89 if (addr_str != NULL)
90 addr = simple_strtoul(addr_str, NULL, 16);
91 else
92 addr = CONFIG_SYS_LOAD_ADDR;
93
94 break;
95 case 4:
96 break;
97 case 5:
98 filename = argv[4];
99 break;
100 case 6:
101 filename = argv[4];
102 count = simple_strtoul(argv[5], NULL, 16);
103 break;
104
105 default:
106 return cmd_usage(cmdtp);
107 }
108
109 if (!filename) {
110 puts("** No boot file defined **\n");
111 return 1;
112 }
113
114 dev = (int)simple_strtoul(argv[2], &ep, 16);
115 ext4_dev_desc = get_dev(argv[1], dev);
116 if (ext4_dev_desc == NULL) {
117 printf("** Block device %s %d not supported\n", argv[1], dev);
118 return 1;
119 }
120 if (init_fs(ext4_dev_desc))
121 return 1;
122
123 fs = get_fs();
124 if (*ep) {
125 if (*ep != ':') {
126 puts("** Invalid boot device, use `dev[:part]' **\n");
127 goto fail;
128 }
129 part = simple_strtoul(++ep, NULL, 16);
130 }
131
132 if (part != 0) {
133 if (get_partition_info(fs->dev_desc, part, &info)) {
134 printf("** Bad partition %lu **\n", part);
135 goto fail;
136 }
137
138 if (strncmp((char *)info.type, BOOT_PART_TYPE,
139 strlen(BOOT_PART_TYPE)) != 0) {
140 printf("** Invalid partition type \"%s\""
141 " (expect \"" BOOT_PART_TYPE "\")\n", info.type);
142 goto fail;
143 }
144 printf("Loading file \"%s\" "
145 "from %s device %d:%lu %s\n",
146 filename, argv[1], dev, part, info.name);
147 } else {
148 printf("Loading file \"%s\" from %s device %d\n",
149 filename, argv[1], dev);
150 }
151
152 part_length = ext4fs_set_blk_dev(fs->dev_desc, part);
153 if (part_length == 0) {
154 printf("**Bad partition - %s %d:%lu **\n", argv[1], dev, part);
155 ext4fs_close();
156 goto fail;
157 }
158
159 if (!ext4fs_mount(part_length)) {
160 printf("** Bad ext2 partition or disk - %s %d:%lu **\n",
161 argv[1], dev, part);
162 ext4fs_close();
163 goto fail;
164 }
165
166 filelen = ext4fs_open(filename);
167 if (filelen < 0) {
168 printf("** File not found %s\n", filename);
169 ext4fs_close();
170 goto fail;
171 }
172 if ((count < filelen) && (count != 0))
173 filelen = count;
174
175 if (ext4fs_read((char *)addr, filelen) != filelen) {
176 printf("** Unable to read \"%s\" from %s %d:%lu **\n",
177 filename, argv[1], dev, part);
178 ext4fs_close();
179 goto fail;
180 }
181
182 ext4fs_close();
183 deinit_fs(fs->dev_desc);
184 /* Loading ok, update default load address */
185 load_addr = addr;
186
187 printf("%d bytes read\n", filelen);
188 sprintf(buf, "%X", filelen);
189 setenv("filesize", buf);
190
191 return 0;
192fail:
193 deinit_fs(fs->dev_desc);
194 return 1;
195}
196
197int do_ext_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
198{
199 const char *filename = "/";
200 int dev;
201 unsigned long part = 1;
202 char *ep;
203 struct ext_filesystem *fs;
204 int part_length;
205 if (argc < 3)
206 return cmd_usage(cmdtp);
207
208 dev = (int)simple_strtoul(argv[2], &ep, 16);
209
210 ext4_dev_desc = get_dev(argv[1], dev);
211
212 if (ext4_dev_desc == NULL) {
213 printf("\n** Block device %s %d not supported\n", argv[1], dev);
214 return 1;
215 }
216
217 if (init_fs(ext4_dev_desc))
218 return 1;
219
220 fs = get_fs();
221 if (*ep) {
222 if (*ep != ':') {
223 puts("\n** Invalid boot device, use `dev[:part]' **\n");
224 goto fail;
225 }
226 part = simple_strtoul(++ep, NULL, 16);
227 }
228
229 if (argc == 4)
230 filename = argv[3];
231
232 part_length = ext4fs_set_blk_dev(fs->dev_desc, part);
233 if (part_length == 0) {
234 printf("** Bad partition - %s %d:%lu **\n", argv[1], dev, part);
235 ext4fs_close();
236 goto fail;
237 }
238
239 if (!ext4fs_mount(part_length)) {
240 printf("** Bad ext2 partition or disk - %s %d:%lu **\n",
241 argv[1], dev, part);
242 ext4fs_close();
243 goto fail;
244 }
245
246 if (ext4fs_ls(filename)) {
247 printf("** Error extfs_ls() **\n");
248 ext4fs_close();
249 goto fail;
250 };
251
252 ext4fs_close();
253 deinit_fs(fs->dev_desc);
254 return 0;
255
256fail:
257 deinit_fs(fs->dev_desc);
258 return 1;
259}