]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - common/cmd_ext_common.c
api: net: fix length check in eth_receive()
[karo-tx-uboot.git] / common / cmd_ext_common.c
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 /*
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
67 int 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;
192 fail:
193         deinit_fs(fs->dev_desc);
194         return 1;
195 }
196
197 int 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
256 fail:
257         deinit_fs(fs->dev_desc);
258         return 1;
259 }