]> git.sur5r.net Git - u-boot/blob - common/cmd_ext_common.c
ext4: remove init_fs/deinit_fs
[u-boot] / 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         char buf[12];
79         unsigned long count;
80         const char *addr_str;
81
82         count = 0;
83         addr = simple_strtoul(argv[3], NULL, 16);
84         filename = getenv("bootfile");
85         switch (argc) {
86         case 3:
87                 addr_str = getenv("loadaddr");
88                 if (addr_str != NULL)
89                         addr = simple_strtoul(addr_str, NULL, 16);
90                 else
91                         addr = CONFIG_SYS_LOAD_ADDR;
92
93                 break;
94         case 4:
95                 break;
96         case 5:
97                 filename = argv[4];
98                 break;
99         case 6:
100                 filename = argv[4];
101                 count = simple_strtoul(argv[5], NULL, 16);
102                 break;
103
104         default:
105                 return cmd_usage(cmdtp);
106         }
107
108         if (!filename) {
109                 puts("** No boot file defined **\n");
110                 return 1;
111         }
112
113         dev = (int)simple_strtoul(argv[2], &ep, 16);
114         ext4_dev_desc = get_dev(argv[1], dev);
115         if (ext4_dev_desc == NULL) {
116                 printf("** Block device %s %d not supported\n", argv[1], dev);
117                 return 1;
118         }
119
120         if (*ep) {
121                 if (*ep != ':') {
122                         puts("** Invalid boot device, use `dev[:part]' **\n");
123                         goto fail;
124                 }
125                 part = simple_strtoul(++ep, NULL, 16);
126         }
127
128         if (part != 0) {
129                 if (get_partition_info(ext4_dev_desc, part, &info)) {
130                         printf("** Bad partition %lu **\n", part);
131                         goto fail;
132                 }
133
134                 if (strncmp((char *)info.type, BOOT_PART_TYPE,
135                             strlen(BOOT_PART_TYPE)) != 0) {
136                         printf("** Invalid partition type \"%s\""
137                                " (expect \"" BOOT_PART_TYPE "\")\n", info.type);
138                         goto fail;
139                 }
140                 printf("Loading file \"%s\" "
141                        "from %s device %d:%lu %s\n",
142                        filename, argv[1], dev, part, info.name);
143         } else {
144                 printf("Loading file \"%s\" from %s device %d\n",
145                        filename, argv[1], dev);
146         }
147
148         part_length = ext4fs_set_blk_dev(ext4_dev_desc, part);
149         if (part_length == 0) {
150                 printf("**Bad partition - %s %d:%lu **\n", argv[1], dev, part);
151                 ext4fs_close();
152                 goto fail;
153         }
154
155         if (!ext4fs_mount(part_length)) {
156                 printf("** Bad ext2 partition or disk - %s %d:%lu **\n",
157                        argv[1], dev, part);
158                 ext4fs_close();
159                 goto fail;
160         }
161
162         filelen = ext4fs_open(filename);
163         if (filelen < 0) {
164                 printf("** File not found %s\n", filename);
165                 ext4fs_close();
166                 goto fail;
167         }
168         if ((count < filelen) && (count != 0))
169                 filelen = count;
170
171         if (ext4fs_read((char *)addr, filelen) != filelen) {
172                 printf("** Unable to read \"%s\" from %s %d:%lu **\n",
173                        filename, argv[1], dev, part);
174                 ext4fs_close();
175                 goto fail;
176         }
177
178         ext4fs_close();
179         /* Loading ok, update default load address */
180         load_addr = addr;
181
182         printf("%d bytes read\n", filelen);
183         sprintf(buf, "%X", filelen);
184         setenv("filesize", buf);
185
186         return 0;
187 fail:
188         return 1;
189 }
190
191 int do_ext_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
192 {
193         const char *filename = "/";
194         int dev;
195         unsigned long part = 1;
196         char *ep;
197         int part_length;
198         if (argc < 3)
199                 return cmd_usage(cmdtp);
200
201         dev = (int)simple_strtoul(argv[2], &ep, 16);
202
203         ext4_dev_desc = get_dev(argv[1], dev);
204
205         if (ext4_dev_desc == NULL) {
206                 printf("\n** Block device %s %d not supported\n", argv[1], dev);
207                 return 1;
208         }
209
210         if (*ep) {
211                 if (*ep != ':') {
212                         puts("\n** Invalid boot device, use `dev[:part]' **\n");
213                         goto fail;
214                 }
215                 part = simple_strtoul(++ep, NULL, 16);
216         }
217
218         if (argc == 4)
219                 filename = argv[3];
220
221         part_length = ext4fs_set_blk_dev(ext4_dev_desc, part);
222         if (part_length == 0) {
223                 printf("** Bad partition - %s %d:%lu **\n", argv[1], dev, part);
224                 ext4fs_close();
225                 goto fail;
226         }
227
228         if (!ext4fs_mount(part_length)) {
229                 printf("** Bad ext2 partition or disk - %s %d:%lu **\n",
230                        argv[1], dev, part);
231                 ext4fs_close();
232                 goto fail;
233         }
234
235         if (ext4fs_ls(filename)) {
236                 printf("** Error extfs_ls() **\n");
237                 ext4fs_close();
238                 goto fail;
239         };
240
241         ext4fs_close();
242         return 0;
243
244 fail:
245         return 1;
246 }