summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKoen Kooi <koen@dominion.thruhere.net>2012-05-01 21:06:52 +0200
committerDenys Dmytriyenko <denys@ti.com>2012-05-03 19:09:25 -0400
commit07913cca6cfd7f35a9bb5d6b2cca41c6b5f07ec3 (patch)
tree5a0d8be401a0c7c7eab66ef19081f02e77d6c85d
parentf0e2305c7e1395066b4303b4a891bfb2a066602b (diff)
downloadmeta-ti-07913cca6cfd7f35a9bb5d6b2cca41c6b5f07ec3.tar.gz
u-boot 2011.12: switch beagleboard to ext4 to match beaglebone
Also add patch to increase ext2 read speed. Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> Acked-by: Tom Rini <trini@ti.com> Signed-off-by: Denys Dmytriyenko <denys@ti.com>
-rw-r--r--recipes-bsp/u-boot/u-boot/2011.12/0011-ext2load-increase-read-speed.patch74
-rw-r--r--recipes-bsp/u-boot/u-boot/2011.12/0012-ext4fs-ls-load-support.patch2362
-rw-r--r--recipes-bsp/u-boot/u-boot/2011.12/0013-beagleboard-switch-mmcroots-to-ext4.patch43
-rw-r--r--recipes-bsp/u-boot/u-boot_2011.12.bb5
4 files changed, 2483 insertions, 1 deletions
diff --git a/recipes-bsp/u-boot/u-boot/2011.12/0011-ext2load-increase-read-speed.patch b/recipes-bsp/u-boot/u-boot/2011.12/0011-ext2load-increase-read-speed.patch
new file mode 100644
index 00000000..2adb1db9
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot/2011.12/0011-ext2load-increase-read-speed.patch
@@ -0,0 +1,74 @@
1From e4181abd88a932bc38054af05d39a633656caefa Mon Sep 17 00:00:00 2001
2From: "u-boot@lakedaemon.net" <u-boot@lakedaemon.net>
3Date: Wed, 28 Mar 2012 04:37:11 +0000
4Subject: [PATCH 11/13] ext2load: increase read speed
5
6This patch dramatically drops the amount of time u-boot needs to read a
7file from an ext2 partition. On a typical 2 to 5 MB file (kernels and
8initrds) it goes from tens of seconds to a couple seconds.
9
10All we are doing here is grouping contiguous blocks into one read.
11
12Boot tested on Globalscale Technologies Dreamplug (Kirkwood ARM SoC)
13with three different files. sha1sums were calculated in Linux
14userspace, and then confirmed after ext2load.
15
16Signed-off-by: Jason Cooper <u-boot@lakedaemon.net>
17---
18 fs/ext2/ext2fs.c | 26 ++++++++++++++++++++++++--
19 1 file changed, 24 insertions(+), 2 deletions(-)
20
21diff --git a/fs/ext2/ext2fs.c b/fs/ext2/ext2fs.c
22index e119e13..8531db5 100644
23--- a/fs/ext2/ext2fs.c
24+++ b/fs/ext2/ext2fs.c
25@@ -414,7 +414,6 @@ int ext2fs_read_file
26 if (blknr < 0) {
27 return (-1);
28 }
29- blknr = blknr << log2blocksize;
30
31 /* Last block. */
32 if (i == blockcnt - 1) {
33@@ -432,6 +431,29 @@ int ext2fs_read_file
34 blockend -= skipfirst;
35 }
36
37+ /* grab middle blocks in one go */
38+ if (i != pos / blocksize && i != blockcnt - 1 && blockcnt > 3) {
39+ int oldblk = blknr;
40+ int blocknxt;
41+ while (i < blockcnt - 1) {
42+ blocknxt = ext2fs_read_block(node, i + 1);
43+ if (blocknxt == (oldblk + 1)) {
44+ oldblk = blocknxt;
45+ i++;
46+ } else {
47+ blocknxt = ext2fs_read_block(node, i);
48+ break;
49+ }
50+ }
51+
52+ if (oldblk == blknr)
53+ blockend = blocksize;
54+ else
55+ blockend = (1 + blocknxt - blknr) * blocksize;
56+ }
57+
58+ blknr = blknr << log2blocksize;
59+
60 /* If the block number is 0 this block is not stored on disk but
61 is zero filled instead. */
62 if (blknr) {
63@@ -444,7 +466,7 @@ int ext2fs_read_file
64 } else {
65 memset (buf, 0, blocksize - skipfirst);
66 }
67- buf += blocksize - skipfirst;
68+ buf += blockend - skipfirst;
69 }
70 return (len);
71 }
72--
731.7.10
74
diff --git a/recipes-bsp/u-boot/u-boot/2011.12/0012-ext4fs-ls-load-support.patch b/recipes-bsp/u-boot/u-boot/2011.12/0012-ext4fs-ls-load-support.patch
new file mode 100644
index 00000000..c16a2d8c
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot/2011.12/0012-ext4fs-ls-load-support.patch
@@ -0,0 +1,2362 @@
1From 04a6b1d60a4fec316992b11837d6347117cbb670 Mon Sep 17 00:00:00 2001
2From: "uma.shankar" <uma.shankar@samsung.com>
3Date: Mon, 9 Jan 2012 07:54:50 +0000
4Subject: [PATCH 12/13] ext4fs ls load support
5
6Signed-off-by: Uma Shankar <uma.shankar@samsung.com>
7Signed-off-by: Manjunatha C Achar <a.manjunatha@samsung.com>
8Signed-off-by: Iqbal Shareef <iqbal.ams@samsung.com>
9Signed-off-by: Hakgoo Lee <goodguy.lee@samsung.com>
10---
11 Makefile | 2 +-
12 common/Makefile | 1 +
13 common/cmd_ext4.c | 266 +++++++++++++++
14 fs/Makefile | 1 +
15 fs/ext2/dev.c | 1 +
16 fs/ext2/ext2fs.c | 181 ++--------
17 fs/ext4/Makefile | 51 +++
18 fs/ext4/dev.c | 145 ++++++++
19 fs/ext4/ext4_common.c | 875 +++++++++++++++++++++++++++++++++++++++++++++++++
20 fs/ext4/ext4_common.h | 63 ++++
21 fs/ext4/ext4fs.c | 228 +++++++++++++
22 include/ext4fs.h | 132 ++++++++
23 include/ext_common.h | 188 +++++++++++
24 13 files changed, 1977 insertions(+), 157 deletions(-)
25 create mode 100644 common/cmd_ext4.c
26 create mode 100644 fs/ext4/Makefile
27 create mode 100644 fs/ext4/dev.c
28 create mode 100644 fs/ext4/ext4_common.c
29 create mode 100644 fs/ext4/ext4_common.h
30 create mode 100644 fs/ext4/ext4fs.c
31 create mode 100644 include/ext4fs.h
32 create mode 100644 include/ext_common.h
33
34diff --git a/Makefile b/Makefile
35index 0438f1e..51cc8c8 100644
36--- a/Makefile
37+++ b/Makefile
38@@ -235,7 +235,7 @@ LIBS += dts/libdts.o
39 endif
40 LIBS += arch/$(ARCH)/lib/lib$(ARCH).o
41 LIBS += fs/cramfs/libcramfs.o fs/fat/libfat.o fs/fdos/libfdos.o fs/jffs2/libjffs2.o \
42- fs/reiserfs/libreiserfs.o fs/ext2/libext2fs.o fs/yaffs2/libyaffs2.o \
43+ fs/reiserfs/libreiserfs.o fs/ext2/libext2fs.o fs/ext4/libext4fs.o fs/yaffs2/libyaffs2.o \
44 fs/ubifs/libubifs.o
45 LIBS += net/libnet.o
46 LIBS += disk/libdisk.o
47diff --git a/common/Makefile b/common/Makefile
48index 2d9ae8c..f5243f6 100644
49--- a/common/Makefile
50+++ b/common/Makefile
51@@ -86,6 +86,7 @@ COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += cmd_eeprom.o
52 COBJS-$(CONFIG_CMD_EEPROM) += cmd_eeprom.o
53 COBJS-$(CONFIG_CMD_ELF) += cmd_elf.o
54 COBJS-$(CONFIG_SYS_HUSH_PARSER) += cmd_exit.o
55+COBJS-$(CONFIG_CMD_EXT4) += cmd_ext4.o
56 COBJS-$(CONFIG_CMD_EXT2) += cmd_ext2.o
57 COBJS-$(CONFIG_CMD_FAT) += cmd_fat.o
58 COBJS-$(CONFIG_CMD_FDC)$(CONFIG_CMD_FDOS) += cmd_fdc.o
59diff --git a/common/cmd_ext4.c b/common/cmd_ext4.c
60new file mode 100644
61index 0000000..2c53d2c
62--- /dev/null
63+++ b/common/cmd_ext4.c
64@@ -0,0 +1,266 @@
65+/*
66+ * (C) Copyright 2011 - 2012 Samsung Electronics
67+ * EXT4 filesystem implementation in Uboot by
68+ * Uma Shankar <uma.shankar@samsung.com>
69+ * Manjunatha C Achar <a.manjunatha@samsung.com>
70+ *
71+ * Ext4fs support
72+ * made from existing cmd_ext2.c file of Uboot
73+ *
74+ * (C) Copyright 2004
75+ * esd gmbh <www.esd-electronics.com>
76+ * Reinhard Arlt <reinhard.arlt@esd-electronics.com>
77+ *
78+ * made from cmd_reiserfs by
79+ *
80+ * (C) Copyright 2003 - 2004
81+ * Sysgo Real-Time Solutions, AG <www.elinos.com>
82+ * Pavel Bartusek <pba@sysgo.com>
83+ *
84+ * This program is free software; you can redistribute it and/or
85+ * modify it under the terms of the GNU General Public License as
86+ * published by the Free Software Foundation; either version 2 of
87+ * the License, or (at your option) any later version.
88+ *
89+ * This program is distributed in the hope that it will be useful,
90+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
91+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
92+ * GNU General Public License for more details.
93+ *
94+ * You should have received a copy of the GNU General Public License
95+ * along with this program; if not, write to the Free Software
96+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
97+ * MA 02111-1307 USA
98+ *
99+ */
100+
101+/*
102+ * Changelog:
103+ * 0.1 - Newly created file for ext4fs support. Taken from cmd_ext2.c
104+ * file in uboot. Added ext4fs ls and load support.
105+ */
106+
107+#include <common.h>
108+#include <part.h>
109+#include <config.h>
110+#include <command.h>
111+#include <image.h>
112+#include <linux/ctype.h>
113+#include <asm/byteorder.h>
114+#include <ext_common.h>
115+#include <ext4fs.h>
116+#include <linux/stat.h>
117+#include <malloc.h>
118+
119+#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
120+#include <usb.h>
121+#endif
122+
123+#if !defined(CONFIG_DOS_PARTITION) && !defined(CONFIG_EFI_PARTITION)
124+#error DOS or EFI partition support must be selected
125+#endif
126+
127+uint64_t total_sector;
128+uint64_t part_offset;
129+
130+#define DOS_PART_MAGIC_OFFSET 0x1fe
131+#define DOS_FS_TYPE_OFFSET 0x36
132+#define DOS_FS32_TYPE_OFFSET 0x52
133+
134+static int do_ext4_load(cmd_tbl_t *cmdtp, int flag, int argc,
135+ char *const argv[])
136+{
137+ char *filename = NULL;
138+ char *ep;
139+ int dev;
140+ unsigned long part = 1;
141+ ulong addr = 0;
142+ ulong part_length;
143+ int filelen;
144+ disk_partition_t info;
145+ struct ext_filesystem *fs;
146+ char buf[12];
147+ unsigned long count;
148+ const char *addr_str;
149+
150+ count = 0;
151+ addr = simple_strtoul(argv[3], NULL, 16);
152+ filename = getenv("bootfile");
153+ switch (argc) {
154+ case 3:
155+ addr_str = getenv("loadaddr");
156+ if (addr_str != NULL)
157+ addr = simple_strtoul(addr_str, NULL, 16);
158+ else
159+ addr = CONFIG_SYS_LOAD_ADDR;
160+
161+ break;
162+ case 4:
163+ break;
164+ case 5:
165+ filename = argv[4];
166+ break;
167+ case 6:
168+ filename = argv[4];
169+ count = simple_strtoul(argv[5], NULL, 16);
170+ break;
171+
172+ default:
173+ return cmd_usage(cmdtp);
174+ }
175+
176+ if (!filename) {
177+ puts("** No boot file defined **\n");
178+ return 1;
179+ }
180+
181+ dev = (int)simple_strtoul(argv[2], &ep, 16);
182+ ext4_dev_desc = get_dev(argv[1], dev);
183+ if (ext4_dev_desc == NULL) {
184+ printf("** Block device %s %d not supported\n", argv[1], dev);
185+ return 1;
186+ }
187+ if (init_fs(ext4_dev_desc))
188+ return 1;
189+
190+ fs = get_fs();
191+ if (*ep) {
192+ if (*ep != ':') {
193+ puts("** Invalid boot device, use `dev[:part]' **\n");
194+ return 1;
195+ }
196+ part = simple_strtoul(++ep, NULL, 16);
197+ }
198+
199+ if (part != 0) {
200+ if (get_partition_info(fs->dev_desc, part, &info)) {
201+ printf("** Bad partition %lu **\n", part);
202+ return 1;
203+ }
204+
205+ if (strncmp((char *)info.type, BOOT_PART_TYPE,
206+ strlen(BOOT_PART_TYPE)) != 0) {
207+ printf("** Invalid partition type \"%s\""
208+ " (expect \"" BOOT_PART_TYPE "\")\n", info.type);
209+ return 1;
210+ }
211+ printf("Loading file \"%s\" "
212+ "from %s device %d:%lu %s\n",
213+ filename, argv[1], dev, part, info.name);
214+ } else {
215+ printf("Loading file \"%s\" from %s device %d\n",
216+ filename, argv[1], dev);
217+ }
218+
219+ part_length = ext4fs_set_blk_dev(fs->dev_desc, part);
220+ if (part_length == 0) {
221+ printf("**Bad partition - %s %d:%lu **\n", argv[1], dev, part);
222+ ext4fs_close();
223+ return 1;
224+ }
225+
226+ if (!ext4fs_mount(part_length)) {
227+ printf("** Bad ext2 partition or disk - %s %d:%lu **\n",
228+ argv[1], dev, part);
229+ ext4fs_close();
230+ return 1;
231+ }
232+
233+ filelen = ext4fs_open(filename);
234+ if (filelen < 0) {
235+ printf("** File not found %s\n", filename);
236+ ext4fs_close();
237+ return 1;
238+ }
239+ if ((count < filelen) && (count != 0))
240+ filelen = count;
241+
242+ if (ext4fs_read((char *)addr, filelen) != filelen) {
243+ printf("** Unable to read \"%s\" from %s %d:%lu **\n",
244+ filename, argv[1], dev, part);
245+ ext4fs_close();
246+ return 1;
247+ }
248+
249+ ext4fs_close();
250+ deinit_fs(fs->dev_desc);
251+ /* Loading ok, update default load address */
252+ load_addr = addr;
253+
254+ printf("%d bytes read\n", filelen);
255+ sprintf(buf, "%X", filelen);
256+ setenv("filesize", buf);
257+
258+ return 0;
259+}
260+
261+static int do_ext4_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
262+{
263+ const char *filename = "/";
264+ int dev;
265+ unsigned long part = 1;
266+ char *ep;
267+ struct ext_filesystem *fs;
268+ int part_length;
269+
270+ if (argc < 3)
271+ return cmd_usage(cmdtp);
272+
273+ dev = (int)simple_strtoul(argv[2], &ep, 16);
274+ ext4_dev_desc = get_dev(argv[1], dev);
275+
276+ if (ext4_dev_desc == NULL) {
277+ printf("\n** Block device %s %d not supported\n", argv[1], dev);
278+ return 1;
279+ }
280+
281+ if (init_fs(ext4_dev_desc))
282+ return 1;
283+
284+ fs = get_fs();
285+ if (*ep) {
286+ if (*ep != ':') {
287+ puts("\n** Invalid boot device, use `dev[:part]' **\n");
288+ return 1;
289+ }
290+ part = simple_strtoul(++ep, NULL, 16);
291+ }
292+
293+ if (argc == 4)
294+ filename = argv[3];
295+
296+ part_length = ext4fs_set_blk_dev(fs->dev_desc, part);
297+ if (part_length == 0) {
298+ printf("** Bad partition - %s %d:%lu **\n", argv[1], dev, part);
299+ ext4fs_close();
300+ return 1;
301+ }
302+
303+ if (!ext4fs_mount(part_length)) {
304+ printf("** Bad ext2 partition or disk - %s %d:%lu **\n",
305+ argv[1], dev, part);
306+ ext4fs_close();
307+ return 1;
308+ }
309+ if (ext4fs_ls(filename)) {
310+ printf("** Error ext2fs_ls() **\n");
311+ ext4fs_close();
312+ return 1;
313+ };
314+
315+ ext4fs_close();
316+ deinit_fs(fs->dev_desc);
317+
318+ return 0;
319+}
320+
321+U_BOOT_CMD(ext4ls, 4, 1, do_ext4_ls,
322+ "list files in a directory (default /)",
323+ "<interface> <dev[:part]> [directory]\n"
324+ " - list files from 'dev' on 'interface' in a 'directory'");
325+
326+U_BOOT_CMD(ext4load, 6, 0, do_ext4_load,
327+ "load binary file from a Ext2 filesystem",
328+ "<interface> <dev[:part]> [addr] [filename] [bytes]\n"
329+ " - load binary file 'filename' from 'dev' on 'interface'\n"
330+ " to address 'addr' from ext2 filesystem");
331diff --git a/fs/Makefile b/fs/Makefile
332index 22aad12..00a8f37 100644
333--- a/fs/Makefile
334+++ b/fs/Makefile
335@@ -23,6 +23,7 @@
336 #
337
338 subdirs-$(CONFIG_CMD_CRAMFS) := cramfs
339+subdirs-$(CONFIG_CMD_EXT4) += ext4
340 subdirs-$(CONFIG_CMD_EXT2) += ext2
341 subdirs-$(CONFIG_CMD_FAT) += fat
342 subdirs-$(CONFIG_CMD_FDOS) += fdos
343diff --git a/fs/ext2/dev.c b/fs/ext2/dev.c
344index 874e211..315ff53 100644
345--- a/fs/ext2/dev.c
346+++ b/fs/ext2/dev.c
347@@ -27,6 +27,7 @@
348 #include <common.h>
349 #include <config.h>
350 #include <ext2fs.h>
351+#include <ext_common.h>
352
353 static block_dev_desc_t *ext2fs_block_dev_desc;
354 static disk_partition_t part_info;
355diff --git a/fs/ext2/ext2fs.c b/fs/ext2/ext2fs.c
356index 8531db5..ea3d98c 100644
357--- a/fs/ext2/ext2fs.c
358+++ b/fs/ext2/ext2fs.c
359@@ -25,152 +25,16 @@
360
361 #include <common.h>
362 #include <ext2fs.h>
363+#include <ext_common.h>
364 #include <malloc.h>
365 #include <asm/byteorder.h>
366
367 extern int ext2fs_devread (int sector, int byte_offset, int byte_len,
368 char *buf);
369
370-/* Magic value used to identify an ext2 filesystem. */
371-#define EXT2_MAGIC 0xEF53
372-/* Amount of indirect blocks in an inode. */
373-#define INDIRECT_BLOCKS 12
374-/* Maximum lenght of a pathname. */
375-#define EXT2_PATH_MAX 4096
376-/* Maximum nesting of symlinks, used to prevent a loop. */
377-#define EXT2_MAX_SYMLINKCNT 8
378-
379-/* Filetype used in directory entry. */
380-#define FILETYPE_UNKNOWN 0
381-#define FILETYPE_REG 1
382-#define FILETYPE_DIRECTORY 2
383-#define FILETYPE_SYMLINK 7
384-
385-/* Filetype information as used in inodes. */
386-#define FILETYPE_INO_MASK 0170000
387-#define FILETYPE_INO_REG 0100000
388-#define FILETYPE_INO_DIRECTORY 0040000
389-#define FILETYPE_INO_SYMLINK 0120000
390-
391-/* Bits used as offset in sector */
392-#define DISK_SECTOR_BITS 9
393-
394-/* Log2 size of ext2 block in 512 blocks. */
395-#define LOG2_EXT2_BLOCK_SIZE(data) (__le32_to_cpu (data->sblock.log2_block_size) + 1)
396-
397-/* Log2 size of ext2 block in bytes. */
398-#define LOG2_BLOCK_SIZE(data) (__le32_to_cpu (data->sblock.log2_block_size) + 10)
399-
400-/* The size of an ext2 block in bytes. */
401-#define EXT2_BLOCK_SIZE(data) (1 << LOG2_BLOCK_SIZE(data))
402-
403-/* The ext2 superblock. */
404-struct ext2_sblock {
405- uint32_t total_inodes;
406- uint32_t total_blocks;
407- uint32_t reserved_blocks;
408- uint32_t free_blocks;
409- uint32_t free_inodes;
410- uint32_t first_data_block;
411- uint32_t log2_block_size;
412- uint32_t log2_fragment_size;
413- uint32_t blocks_per_group;
414- uint32_t fragments_per_group;
415- uint32_t inodes_per_group;
416- uint32_t mtime;
417- uint32_t utime;
418- uint16_t mnt_count;
419- uint16_t max_mnt_count;
420- uint16_t magic;
421- uint16_t fs_state;
422- uint16_t error_handling;
423- uint16_t minor_revision_level;
424- uint32_t lastcheck;
425- uint32_t checkinterval;
426- uint32_t creator_os;
427- uint32_t revision_level;
428- uint16_t uid_reserved;
429- uint16_t gid_reserved;
430- uint32_t first_inode;
431- uint16_t inode_size;
432- uint16_t block_group_number;
433- uint32_t feature_compatibility;
434- uint32_t feature_incompat;
435- uint32_t feature_ro_compat;
436- uint32_t unique_id[4];
437- char volume_name[16];
438- char last_mounted_on[64];
439- uint32_t compression_info;
440-};
441-
442-/* The ext2 blockgroup. */
443-struct ext2_block_group {
444- uint32_t block_id;
445- uint32_t inode_id;
446- uint32_t inode_table_id;
447- uint16_t free_blocks;
448- uint16_t free_inodes;
449- uint16_t used_dir_cnt;
450- uint32_t reserved[3];
451-};
452-
453-/* The ext2 inode. */
454-struct ext2_inode {
455- uint16_t mode;
456- uint16_t uid;
457- uint32_t size;
458- uint32_t atime;
459- uint32_t ctime;
460- uint32_t mtime;
461- uint32_t dtime;
462- uint16_t gid;
463- uint16_t nlinks;
464- uint32_t blockcnt; /* Blocks of 512 bytes!! */
465- uint32_t flags;
466- uint32_t osd1;
467- union {
468- struct datablocks {
469- uint32_t dir_blocks[INDIRECT_BLOCKS];
470- uint32_t indir_block;
471- uint32_t double_indir_block;
472- uint32_t tripple_indir_block;
473- } blocks;
474- char symlink[60];
475- } b;
476- uint32_t version;
477- uint32_t acl;
478- uint32_t dir_acl;
479- uint32_t fragment_addr;
480- uint32_t osd2[3];
481-};
482-
483-/* The header of an ext2 directory entry. */
484-struct ext2_dirent {
485- uint32_t inode;
486- uint16_t direntlen;
487- uint8_t namelen;
488- uint8_t filetype;
489-};
490-
491-struct ext2fs_node {
492- struct ext2_data *data;
493- struct ext2_inode inode;
494- int ino;
495- int inode_read;
496-};
497-
498-/* Information about a "mounted" ext2 filesystem. */
499-struct ext2_data {
500- struct ext2_sblock sblock;
501- struct ext2_inode *inode;
502- struct ext2fs_node diropen;
503-};
504-
505-
506-typedef struct ext2fs_node *ext2fs_node_t;
507
508 struct ext2_data *ext2fs_root = NULL;
509-ext2fs_node_t ext2fs_file = NULL;
510+struct ext2fs_node *ext2fs_file;
511 int symlinknest = 0;
512 uint32_t *indir1_block = NULL;
513 int indir1_size = 0;
514@@ -243,14 +107,16 @@ static int ext2fs_read_inode
515 }
516
517
518-void ext2fs_free_node (ext2fs_node_t node, ext2fs_node_t currroot) {
519+void ext2fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot)
520+{
521 if ((node != &ext2fs_root->diropen) && (node != currroot)) {
522 free (node);
523 }
524 }
525
526
527-static int ext2fs_read_block (ext2fs_node_t node, int fileblock) {
528+static int ext2fs_read_block(struct ext2fs_node *node, int fileblock)
529+{
530 struct ext2_data *data = node->data;
531 struct ext2_inode *inode = &node->inode;
532 int blknr;
533@@ -390,7 +256,8 @@ static int ext2fs_read_block (ext2fs_node_t node, int fileblock) {
534
535
536 int ext2fs_read_file
537- (ext2fs_node_t node, int pos, unsigned int len, char *buf) {
538+ (struct ext2fs_node *node, int pos, unsigned int len, char *buf)
539+{
540 int i;
541 int blockcnt;
542 int log2blocksize = LOG2_EXT2_BLOCK_SIZE (node->data);
543@@ -471,8 +338,8 @@ int ext2fs_read_file
544 return (len);
545 }
546
547-
548-static int ext2fs_iterate_dir (ext2fs_node_t dir, char *name, ext2fs_node_t * fnode, int *ftype)
549+int ext2fs_iterate_dir(struct ext2fs_node *dir, char *name,
550+ struct ext2fs_node **fnode, int *ftype)
551 {
552 unsigned int fpos = 0;
553 int status;
554@@ -501,7 +368,7 @@ static int ext2fs_iterate_dir (ext2fs_node_t dir, char *name, ext2fs_node_t * fn
555 }
556 if (dirent.namelen != 0) {
557 char filename[dirent.namelen + 1];
558- ext2fs_node_t fdiro;
559+ struct ext2fs_node *fdiro;
560 int type = FILETYPE_UNKNOWN;
561
562 status = ext2fs_read_file (diro,
563@@ -603,8 +470,8 @@ static int ext2fs_iterate_dir (ext2fs_node_t dir, char *name, ext2fs_node_t * fn
564 return (0);
565 }
566
567-
568-static char *ext2fs_read_symlink (ext2fs_node_t node) {
569+static char *ext2fs_read_symlink(struct ext2fs_node *node)
570+{
571 char *symlink;
572 struct ext2fs_node *diro = node;
573 int status;
574@@ -641,15 +508,16 @@ static char *ext2fs_read_symlink (ext2fs_node_t node) {
575
576
577 int ext2fs_find_file1
578- (const char *currpath,
579- ext2fs_node_t currroot, ext2fs_node_t * currfound, int *foundtype) {
580+ (const char *currpath, struct ext2fs_node *currroot,
581+ struct ext2fs_node **currfound, int *foundtype)
582+{
583 char fpath[strlen (currpath) + 1];
584 char *name = fpath;
585 char *next;
586 int status;
587 int type = FILETYPE_DIRECTORY;
588- ext2fs_node_t currnode = currroot;
589- ext2fs_node_t oldnode = currroot;
590+ struct ext2fs_node *currnode = currroot;
591+ struct ext2fs_node *oldnode = currroot;
592
593 strncpy (fpath, currpath, strlen (currpath) + 1);
594
595@@ -745,8 +613,9 @@ int ext2fs_find_file1
596
597
598 int ext2fs_find_file
599- (const char *path,
600- ext2fs_node_t rootnode, ext2fs_node_t * foundnode, int expecttype) {
601+ (const char *path, struct ext2fs_node *rootnode,
602+ struct ext2fs_node **foundnode, int expecttype)
603+{
604 int status;
605 int foundtype = FILETYPE_DIRECTORY;
606
607@@ -772,7 +641,7 @@ int ext2fs_find_file
608
609
610 int ext2fs_ls (const char *dirname) {
611- ext2fs_node_t dirnode;
612+ struct ext2fs_node *dirnode;
613 int status;
614
615 if (ext2fs_root == NULL) {
616@@ -792,7 +661,7 @@ int ext2fs_ls (const char *dirname) {
617
618
619 int ext2fs_open (const char *filename) {
620- ext2fs_node_t fdiro = NULL;
621+ struct ext2fs_node *fdiro = NULL;
622 int status;
623 int len;
624
625@@ -822,8 +691,8 @@ fail:
626 }
627
628
629-int ext2fs_close (void
630- ) {
631+int ext2fs_close(void)
632+{
633 if ((ext2fs_file != NULL) && (ext2fs_root != NULL)) {
634 ext2fs_free_node (ext2fs_file, &ext2fs_root->diropen);
635 ext2fs_file = NULL;
636diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile
637new file mode 100644
638index 0000000..7add4ab
639--- /dev/null
640+++ b/fs/ext4/Makefile
641@@ -0,0 +1,51 @@
642+#
643+# (C) Copyright 2006
644+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
645+#
646+# (C) Copyright 2003
647+# Pavel Bartusek, Sysgo Real-Time Solutions AG, pba@sysgo.de
648+#
649+#
650+# See file CREDITS for list of people who contributed to this
651+# project.
652+#
653+# This program is free software; you can redistribute it and/or
654+# modify it under the terms of the GNU General Public License as
655+# published by the Free Software Foundation; either version 2 of
656+# the License, or (at your option) any later version.
657+#
658+# This program is distributed in the hope that it will be useful,
659+# but WITHOUT ANY WARRANTY; without even the implied warranty of
660+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
661+# GNU General Public License for more details.
662+#
663+# You should have received a copy of the GNU General Public License
664+# along with this program; if not, write to the Free Software
665+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
666+# MA 02111-1307 USA
667+#
668+
669+include $(TOPDIR)/config.mk
670+
671+LIB = $(obj)libext4fs.o
672+
673+AOBJS =
674+COBJS-$(CONFIG_CMD_EXT4) := ext4fs.o ext4_common.o dev.o
675+
676+SRCS := $(AOBJS:.o=.S) $(COBJS-y:.o=.c)
677+OBJS := $(addprefix $(obj),$(AOBJS) $(COBJS-y))
678+
679+
680+all: $(LIB) $(AOBJS)
681+
682+$(LIB): $(obj).depend $(OBJS)
683+ $(call cmd_link_o_target, $(OBJS))
684+
685+#########################################################################
686+
687+# defines $(obj).depend target
688+include $(SRCTREE)/rules.mk
689+
690+sinclude $(obj).depend
691+
692+#########################################################################
693diff --git a/fs/ext4/dev.c b/fs/ext4/dev.c
694new file mode 100644
695index 0000000..2054be3
696--- /dev/null
697+++ b/fs/ext4/dev.c
698@@ -0,0 +1,145 @@
699+/*
700+ * (C) Copyright 2011 - 2012 Samsung Electronics
701+ * EXT4 filesystem implementation in Uboot by
702+ * Uma Shankar <uma.shankar@samsung.com>
703+ * Manjunatha C Achar <a.manjunatha@samsung.com>
704+ *
705+ * made from existing ext2/dev.c file of Uboot
706+ * (C) Copyright 2004
707+ * esd gmbh <www.esd-electronics.com>
708+ * Reinhard Arlt <reinhard.arlt@esd-electronics.com>
709+ *
710+ * based on code of fs/reiserfs/dev.c by
711+ *
712+ * (C) Copyright 2003 - 2004
713+ * Sysgo AG, <www.elinos.com>, Pavel Bartusek <pba@sysgo.com>
714+ *
715+ * This program is free software; you can redistribute it and/or modify
716+ * it under the terms of the GNU General Public License as published by
717+ * the Free Software Foundation; either version 2 of the License, or
718+ * (at your option) any later version.
719+ *
720+ * This program is distributed in the hope that it will be useful,
721+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
722+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
723+ * GNU General Public License for more details.
724+ *
725+ * You should have received a copy of the GNU General Public License
726+ * along with this program; if not, write to the Free Software
727+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
728+ *
729+ */
730+
731+/*
732+ * Changelog:
733+ * 0.1 - Newly created file for ext4fs support. Taken from
734+ * fs/ext2/dev.c file in uboot.
735+ */
736+
737+#include <common.h>
738+#include <config.h>
739+#include <ext_common.h>
740+
741+static block_dev_desc_t *ext4fs_block_dev_desc;
742+static disk_partition_t part_info;
743+
744+int ext4fs_set_blk_dev(block_dev_desc_t *rbdd, int part)
745+{
746+ ext4fs_block_dev_desc = rbdd;
747+
748+ if (part == 0) {
749+ /* disk doesn't use partition table */
750+ part_info.start = 0;
751+ part_info.size = rbdd->lba;
752+ part_info.blksz = rbdd->blksz;
753+ } else {
754+ if (get_partition_info(ext4fs_block_dev_desc,
755+ part, &part_info))
756+ return 0;
757+ }
758+ return part_info.size;
759+}
760+
761+int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
762+{
763+ char sec_buf[SECTOR_SIZE];
764+ unsigned block_len;
765+
766+ /* Check partition boundaries */
767+ if ((sector < 0)
768+ || ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) >=
769+ part_info.size)) {
770+ printf("%s read outside partition %d\n", __func__, sector);
771+ return 0;
772+ }
773+
774+ /* Get the read to the beginning of a partition */
775+ sector += byte_offset >> SECTOR_BITS;
776+ byte_offset &= SECTOR_SIZE - 1;
777+
778+ debug(" <%d, %d, %d>\n", sector, byte_offset, byte_len);
779+
780+ if (ext4fs_block_dev_desc == NULL) {
781+ printf("** Invalid Block Device Descriptor (NULL)\n");
782+ return 0;
783+ }
784+
785+ if (byte_offset != 0) {
786+ /* read first part which isn't aligned with start of sector */
787+ if (ext4fs_block_dev_desc->
788+ block_read(ext4fs_block_dev_desc->dev,
789+ part_info.start + sector, 1,
790+ (unsigned long *) sec_buf) != 1) {
791+ printf(" ** ext2fs_devread() read error **\n");
792+ return 0;
793+ }
794+ memcpy(buf, sec_buf + byte_offset,
795+ min(SECTOR_SIZE - byte_offset, byte_len));
796+ buf += min(SECTOR_SIZE - byte_offset, byte_len);
797+ byte_len -= min(SECTOR_SIZE - byte_offset, byte_len);
798+ sector++;
799+ }
800+
801+ if (byte_len == 0)
802+ return 1;
803+
804+ /* read sector aligned part */
805+ block_len = byte_len & ~(SECTOR_SIZE - 1);
806+
807+ if (block_len == 0) {
808+ u8 p[SECTOR_SIZE];
809+
810+ block_len = SECTOR_SIZE;
811+ ext4fs_block_dev_desc->block_read(ext4fs_block_dev_desc->dev,
812+ part_info.start + sector,
813+ 1, (unsigned long *)p);
814+ memcpy(buf, p, byte_len);
815+ return 1;
816+ }
817+
818+ if (ext4fs_block_dev_desc->block_read(ext4fs_block_dev_desc->dev,
819+ part_info.start + sector,
820+ block_len / SECTOR_SIZE,
821+ (unsigned long *) buf) !=
822+ block_len / SECTOR_SIZE) {
823+ printf(" ** %s read error - block\n", __func__);
824+ return 0;
825+ }
826+ block_len = byte_len & ~(SECTOR_SIZE - 1);
827+ buf += block_len;
828+ byte_len -= block_len;
829+ sector += block_len / SECTOR_SIZE;
830+
831+ if (byte_len != 0) {
832+ /* read rest of data which are not in whole sector */
833+ if (ext4fs_block_dev_desc->
834+ block_read(ext4fs_block_dev_desc->dev,
835+ part_info.start + sector, 1,
836+ (unsigned long *) sec_buf) != 1) {
837+ printf("* %s read error - last part\n", __func__);
838+ return 0;
839+ }
840+ memcpy(buf, sec_buf, byte_len);
841+ }
842+ return 1;
843+}
844diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
845new file mode 100644
846index 0000000..d9deefe
847--- /dev/null
848+++ b/fs/ext4/ext4_common.c
849@@ -0,0 +1,875 @@
850+/*
851+ * (C) Copyright 2011 - 2012 Samsung Electronics
852+ * EXT4 filesystem implementation in Uboot by
853+ * Uma Shankar <uma.shankar@samsung.com>
854+ * Manjunatha C Achar <a.manjunatha@samsung.com>
855+ *
856+ * ext4ls and ext4load : Based on ext2 ls load support in Uboot.
857+ *
858+ * (C) Copyright 2004
859+ * esd gmbh <www.esd-electronics.com>
860+ * Reinhard Arlt <reinhard.arlt@esd-electronics.com>
861+ *
862+ * based on code from grub2 fs/ext2.c and fs/fshelp.c by
863+ * GRUB -- GRand Unified Bootloader
864+ * Copyright (C) 2003, 2004 Free Software Foundation, Inc.
865+ *
866+ * This program is free software; you can redistribute it and/or modify
867+ * it under the terms of the GNU General Public License as published by
868+ * the Free Software Foundation; either version 2 of the License, or
869+ * (at your option) any later version.
870+ *
871+ * This program is distributed in the hope that it will be useful,
872+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
873+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
874+ * GNU General Public License for more details.
875+ *
876+ * You should have received a copy of the GNU General Public License
877+ * along with this program; if not, write to the Free Software
878+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
879+ */
880+
881+#include <common.h>
882+#include <ext_common.h>
883+#include <ext4fs.h>
884+#include <malloc.h>
885+#include <stddef.h>
886+#include <linux/stat.h>
887+#include <linux/time.h>
888+#include <asm/byteorder.h>
889+#include "ext4_common.h"
890+
891+struct ext2_data *ext4fs_root;
892+struct ext2fs_node *ext4fs_file;
893+uint32_t *ext4fs_indir1_block;
894+int ext4fs_indir1_size;
895+int ext4fs_indir1_blkno = -1;
896+uint32_t *ext4fs_indir2_block;
897+int ext4fs_indir2_size;
898+int ext4fs_indir2_blkno = -1;
899+
900+uint32_t *ext4fs_indir3_block;
901+int ext4fs_indir3_size;
902+int ext4fs_indir3_blkno = -1;
903+struct ext2_inode *g_parent_inode;
904+static int symlinknest;
905+
906+static struct ext4_extent_header *ext4fs_get_extent_block
907+ (struct ext2_data *data, char *buf,
908+ struct ext4_extent_header *ext_block,
909+ uint32_t fileblock, int log2_blksz)
910+{
911+ struct ext4_extent_idx *index;
912+ unsigned long long block;
913+ struct ext_filesystem *fs = get_fs();
914+ int i;
915+
916+ while (1) {
917+ index = (struct ext4_extent_idx *)(ext_block + 1);
918+
919+ if (le32_to_cpu(ext_block->eh_magic) != EXT4_EXT_MAGIC)
920+ return 0;
921+
922+ if (ext_block->eh_depth == 0)
923+ return ext_block;
924+ i = -1;
925+ do {
926+ i++;
927+ if (i >= le32_to_cpu(ext_block->eh_entries))
928+ break;
929+ } while (fileblock > le32_to_cpu(index[i].ei_block));
930+
931+ if (--i < 0)
932+ return 0;
933+
934+ block = le32_to_cpu(index[i].ei_leaf_hi);
935+ block = (block << 32) + le32_to_cpu(index[i].ei_leaf_lo);
936+
937+ if (ext4fs_devread(block << log2_blksz, 0, fs->blksz, buf))
938+ ext_block = (struct ext4_extent_header *)buf;
939+ else
940+ return 0;
941+ }
942+}
943+
944+static int ext4fs_blockgroup
945+ (struct ext2_data *data, int group, struct ext2_block_group *blkgrp)
946+{
947+ long int blkno;
948+ unsigned int blkoff, desc_per_blk;
949+
950+ desc_per_blk = EXT2_BLOCK_SIZE(data) / sizeof(struct ext2_block_group);
951+
952+ blkno = __le32_to_cpu(data->sblock.first_data_block) + 1 +
953+ group / desc_per_blk;
954+ blkoff = (group % desc_per_blk) * sizeof(struct ext2_block_group);
955+
956+ debug("ext4fs read %d group descriptor (blkno %ld blkoff %u)\n",
957+ group, blkno, blkoff);
958+
959+ return ext4fs_devread(blkno << LOG2_EXT2_BLOCK_SIZE(data),
960+ blkoff, sizeof(struct ext2_block_group),
961+ (char *)blkgrp);
962+}
963+
964+int ext4fs_read_inode(struct ext2_data *data, int ino, struct ext2_inode *inode)
965+{
966+ struct ext2_block_group blkgrp;
967+ struct ext2_sblock *sblock = &data->sblock;
968+ struct ext_filesystem *fs = get_fs();
969+ int inodes_per_block, status;
970+ long int blkno;
971+ unsigned int blkoff;
972+
973+ /* It is easier to calculate if the first inode is 0. */
974+ ino--;
975+ status = ext4fs_blockgroup(data, ino / __le32_to_cpu
976+ (sblock->inodes_per_group), &blkgrp);
977+ if (status == 0)
978+ return 0;
979+
980+ inodes_per_block = EXT2_BLOCK_SIZE(data) / fs->inodesz;
981+ blkno = __le32_to_cpu(blkgrp.inode_table_id) +
982+ (ino % __le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block;
983+ blkoff = (ino % inodes_per_block) * fs->inodesz;
984+ /* Read the inode. */
985+ status = ext4fs_devread(blkno << LOG2_EXT2_BLOCK_SIZE(data), blkoff,
986+ sizeof(struct ext2_inode), (char *)inode);
987+ if (status == 0)
988+ return 0;
989+
990+ return 1;
991+}
992+
993+long int read_allocated_block(struct ext2_inode *inode, int fileblock)
994+{
995+ long int blknr;
996+ int blksz;
997+ int log2_blksz;
998+ int status;
999+ long int rblock;
1000+ long int perblock_parent;
1001+ long int perblock_child;
1002+ unsigned long long start;
1003+ /* get the blocksize of the filesystem */
1004+ blksz = EXT2_BLOCK_SIZE(ext4fs_root);
1005+ log2_blksz = LOG2_EXT2_BLOCK_SIZE(ext4fs_root);
1006+ if (le32_to_cpu(inode->flags) & EXT4_EXTENTS_FL) {
1007+ char *buf = zalloc(blksz);
1008+ if (!buf)
1009+ return -ENOMEM;
1010+ struct ext4_extent_header *ext_block;
1011+ struct ext4_extent *extent;
1012+ int i = -1;
1013+ ext_block = ext4fs_get_extent_block(ext4fs_root, buf,
1014+ (struct ext4_extent_header
1015+ *)inode->b.
1016+ blocks.dir_blocks,
1017+ fileblock, log2_blksz);
1018+ if (!ext_block) {
1019+ printf("invalid extent block\n");
1020+ free(buf);
1021+ return -EINVAL;
1022+ }
1023+
1024+ extent = (struct ext4_extent *)(ext_block + 1);
1025+
1026+ do {
1027+ i++;
1028+ if (i >= le32_to_cpu(ext_block->eh_entries))
1029+ break;
1030+ } while (fileblock >= le32_to_cpu(extent[i].ee_block));
1031+ if (--i >= 0) {
1032+ fileblock -= le32_to_cpu(extent[i].ee_block);
1033+ if (fileblock >= le32_to_cpu(extent[i].ee_len)) {
1034+ free(buf);
1035+ return 0;
1036+ }
1037+
1038+ start = le32_to_cpu(extent[i].ee_start_hi);
1039+ start = (start << 32) +
1040+ le32_to_cpu(extent[i].ee_start_lo);
1041+ free(buf);
1042+ return fileblock + start;
1043+ }
1044+
1045+ printf("Extent Error\n");
1046+ free(buf);
1047+ return -1;
1048+ }
1049+
1050+ /* Direct blocks. */
1051+ if (fileblock < INDIRECT_BLOCKS)
1052+ blknr = __le32_to_cpu(inode->b.blocks.dir_blocks[fileblock]);
1053+
1054+ /* Indirect. */
1055+ else if (fileblock < (INDIRECT_BLOCKS + (blksz / 4))) {
1056+ if (ext4fs_indir1_block == NULL) {
1057+ ext4fs_indir1_block = zalloc(blksz);
1058+ if (ext4fs_indir1_block == NULL) {
1059+ printf("** SI ext2fs read block (indir 1)"
1060+ "malloc failed. **\n");
1061+ return -1;
1062+ }
1063+ ext4fs_indir1_size = blksz;
1064+ ext4fs_indir1_blkno = -1;
1065+ }
1066+ if (blksz != ext4fs_indir1_size) {
1067+ free(ext4fs_indir1_block);
1068+ ext4fs_indir1_block = NULL;
1069+ ext4fs_indir1_size = 0;
1070+ ext4fs_indir1_blkno = -1;
1071+ ext4fs_indir1_block = zalloc(blksz);
1072+ if (ext4fs_indir1_block == NULL) {
1073+ printf("** SI ext2fs read block (indir 1):"
1074+ "malloc failed. **\n");
1075+ return -1;
1076+ }
1077+ ext4fs_indir1_size = blksz;
1078+ }
1079+ if ((__le32_to_cpu(inode->b.blocks.indir_block) <<
1080+ log2_blksz) != ext4fs_indir1_blkno) {
1081+ status =
1082+ ext4fs_devread(__le32_to_cpu
1083+ (inode->b.blocks.
1084+ indir_block) << log2_blksz, 0,
1085+ blksz, (char *)ext4fs_indir1_block);
1086+ if (status == 0) {
1087+ printf("** SI ext2fs read block (indir 1)"
1088+ "failed. **\n");
1089+ return 0;
1090+ }
1091+ ext4fs_indir1_blkno =
1092+ __le32_to_cpu(inode->b.blocks.
1093+ indir_block) << log2_blksz;
1094+ }
1095+ blknr = __le32_to_cpu(ext4fs_indir1_block
1096+ [fileblock - INDIRECT_BLOCKS]);
1097+ }
1098+ /* Double indirect. */
1099+ else if (fileblock < (INDIRECT_BLOCKS + (blksz / 4 *
1100+ (blksz / 4 + 1)))) {
1101+
1102+ long int perblock = blksz / 4;
1103+ long int rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4);
1104+
1105+ if (ext4fs_indir1_block == NULL) {
1106+ ext4fs_indir1_block = zalloc(blksz);
1107+ if (ext4fs_indir1_block == NULL) {
1108+ printf("** DI ext2fs read block (indir 2 1)"
1109+ "malloc failed. **\n");
1110+ return -1;
1111+ }
1112+ ext4fs_indir1_size = blksz;
1113+ ext4fs_indir1_blkno = -1;
1114+ }
1115+ if (blksz != ext4fs_indir1_size) {
1116+ free(ext4fs_indir1_block);
1117+ ext4fs_indir1_block = NULL;
1118+ ext4fs_indir1_size = 0;
1119+ ext4fs_indir1_blkno = -1;
1120+ ext4fs_indir1_block = zalloc(blksz);
1121+ if (ext4fs_indir1_block == NULL) {
1122+ printf("** DI ext2fs read block (indir 2 1)"
1123+ "malloc failed. **\n");
1124+ return -1;
1125+ }
1126+ ext4fs_indir1_size = blksz;
1127+ }
1128+ if ((__le32_to_cpu(inode->b.blocks.double_indir_block) <<
1129+ log2_blksz) != ext4fs_indir1_blkno) {
1130+ status =
1131+ ext4fs_devread(__le32_to_cpu
1132+ (inode->b.blocks.
1133+ double_indir_block) << log2_blksz,
1134+ 0, blksz,
1135+ (char *)ext4fs_indir1_block);
1136+ if (status == 0) {
1137+ printf("** DI ext2fs read block (indir 2 1)"
1138+ "failed. **\n");
1139+ return -1;
1140+ }
1141+ ext4fs_indir1_blkno =
1142+ __le32_to_cpu(inode->b.blocks.double_indir_block) <<
1143+ log2_blksz;
1144+ }
1145+
1146+ if (ext4fs_indir2_block == NULL) {
1147+ ext4fs_indir2_block = zalloc(blksz);
1148+ if (ext4fs_indir2_block == NULL) {
1149+ printf("** DI ext2fs read block (indir 2 2)"
1150+ "malloc failed. **\n");
1151+ return -1;
1152+ }
1153+ ext4fs_indir2_size = blksz;
1154+ ext4fs_indir2_blkno = -1;
1155+ }
1156+ if (blksz != ext4fs_indir2_size) {
1157+ free(ext4fs_indir2_block);
1158+ ext4fs_indir2_block = NULL;
1159+ ext4fs_indir2_size = 0;
1160+ ext4fs_indir2_blkno = -1;
1161+ ext4fs_indir2_block = zalloc(blksz);
1162+ if (ext4fs_indir2_block == NULL) {
1163+ printf("** DI ext2fs read block (indir 2 2)"
1164+ "malloc failed. **\n");
1165+ return -1;
1166+ }
1167+ ext4fs_indir2_size = blksz;
1168+ }
1169+ if ((__le32_to_cpu(ext4fs_indir1_block[rblock / perblock]) <<
1170+ log2_blksz) != ext4fs_indir2_blkno) {
1171+ status = ext4fs_devread(__le32_to_cpu
1172+ (ext4fs_indir1_block
1173+ [rblock /
1174+ perblock]) << log2_blksz, 0,
1175+ blksz,
1176+ (char *)ext4fs_indir2_block);
1177+ if (status == 0) {
1178+ printf("** DI ext2fs read block (indir 2 2)"
1179+ "failed. **\n");
1180+ return -1;
1181+ }
1182+ ext4fs_indir2_blkno =
1183+ __le32_to_cpu(ext4fs_indir1_block[rblock
1184+ /
1185+ perblock]) <<
1186+ log2_blksz;
1187+ }
1188+ blknr = __le32_to_cpu(ext4fs_indir2_block[rblock % perblock]);
1189+ }
1190+ /* Tripple indirect. */
1191+ else {
1192+ rblock = fileblock - (INDIRECT_BLOCKS + blksz / 4 +
1193+ (blksz / 4 * blksz / 4));
1194+ perblock_child = blksz / 4;
1195+ perblock_parent = ((blksz / 4) * (blksz / 4));
1196+
1197+ if (ext4fs_indir1_block == NULL) {
1198+ ext4fs_indir1_block = zalloc(blksz);
1199+ if (ext4fs_indir1_block == NULL) {
1200+ printf("** TI ext2fs read block (indir 2 1)"
1201+ "malloc failed. **\n");
1202+ return -1;
1203+ }
1204+ ext4fs_indir1_size = blksz;
1205+ ext4fs_indir1_blkno = -1;
1206+ }
1207+ if (blksz != ext4fs_indir1_size) {
1208+ free(ext4fs_indir1_block);
1209+ ext4fs_indir1_block = NULL;
1210+ ext4fs_indir1_size = 0;
1211+ ext4fs_indir1_blkno = -1;
1212+ ext4fs_indir1_block = zalloc(blksz);
1213+ if (ext4fs_indir1_block == NULL) {
1214+ printf("** TI ext2fs read block (indir 2 1)"
1215+ "malloc failed. **\n");
1216+ return -1;
1217+ }
1218+ ext4fs_indir1_size = blksz;
1219+ }
1220+ if ((__le32_to_cpu(inode->b.blocks.triple_indir_block) <<
1221+ log2_blksz) != ext4fs_indir1_blkno) {
1222+ status = ext4fs_devread
1223+ (__le32_to_cpu(inode->b.blocks.triple_indir_block)
1224+ << log2_blksz, 0, blksz,
1225+ (char *)ext4fs_indir1_block);
1226+ if (status == 0) {
1227+ printf("** TI ext2fs read block (indir 2 1)"
1228+ "failed. **\n");
1229+ return -1;
1230+ }
1231+ ext4fs_indir1_blkno =
1232+ __le32_to_cpu(inode->b.blocks.triple_indir_block) <<
1233+ log2_blksz;
1234+ }
1235+
1236+ if (ext4fs_indir2_block == NULL) {
1237+ ext4fs_indir2_block = zalloc(blksz);
1238+ if (ext4fs_indir2_block == NULL) {
1239+ printf("** TI ext2fs read block (indir 2 2)"
1240+ "malloc failed. **\n");
1241+ return -1;
1242+ }
1243+ ext4fs_indir2_size = blksz;
1244+ ext4fs_indir2_blkno = -1;
1245+ }
1246+ if (blksz != ext4fs_indir2_size) {
1247+ free(ext4fs_indir2_block);
1248+ ext4fs_indir2_block = NULL;
1249+ ext4fs_indir2_size = 0;
1250+ ext4fs_indir2_blkno = -1;
1251+ ext4fs_indir2_block = zalloc(blksz);
1252+ if (ext4fs_indir2_block == NULL) {
1253+ printf("** TI ext2fs read block (indir 2 2)"
1254+ "malloc failed. **\n");
1255+ return -1;
1256+ }
1257+ ext4fs_indir2_size = blksz;
1258+ }
1259+ if ((__le32_to_cpu(ext4fs_indir1_block[rblock /
1260+ perblock_parent]) <<
1261+ log2_blksz)
1262+ != ext4fs_indir2_blkno) {
1263+ status = ext4fs_devread(__le32_to_cpu
1264+ (ext4fs_indir1_block
1265+ [rblock /
1266+ perblock_parent]) <<
1267+ log2_blksz, 0, blksz,
1268+ (char *)ext4fs_indir2_block);
1269+ if (status == 0) {
1270+ printf("** TI ext2fs read block (indir 2 2)"
1271+ "failed. **\n");
1272+ return -1;
1273+ }
1274+ ext4fs_indir2_blkno =
1275+ __le32_to_cpu(ext4fs_indir1_block[rblock /
1276+ perblock_parent])
1277+ << log2_blksz;
1278+ }
1279+
1280+ if (ext4fs_indir3_block == NULL) {
1281+ ext4fs_indir3_block = zalloc(blksz);
1282+ if (ext4fs_indir3_block == NULL) {
1283+ printf("** TI ext2fs read block (indir 2 2)"
1284+ "malloc failed. **\n");
1285+ return -1;
1286+ }
1287+ ext4fs_indir3_size = blksz;
1288+ ext4fs_indir3_blkno = -1;
1289+ }
1290+ if (blksz != ext4fs_indir3_size) {
1291+ free(ext4fs_indir3_block);
1292+ ext4fs_indir3_block = NULL;
1293+ ext4fs_indir3_size = 0;
1294+ ext4fs_indir3_blkno = -1;
1295+ ext4fs_indir3_block = zalloc(blksz);
1296+ if (ext4fs_indir3_block == NULL) {
1297+ printf("** TI ext2fs read block (indir 2 2)"
1298+ "malloc failed. **\n");
1299+ return -1;
1300+ }
1301+ ext4fs_indir3_size = blksz;
1302+ }
1303+ if ((__le32_to_cpu(ext4fs_indir2_block[rblock
1304+ /
1305+ perblock_child]) <<
1306+ log2_blksz) != ext4fs_indir3_blkno) {
1307+ status =
1308+ ext4fs_devread(__le32_to_cpu
1309+ (ext4fs_indir2_block
1310+ [(rblock / perblock_child)
1311+ % (blksz / 4)]) << log2_blksz, 0,
1312+ blksz, (char *)ext4fs_indir3_block);
1313+ if (status == 0) {
1314+ printf("** TI ext2fs read block (indir 2 2)"
1315+ "failed. **\n");
1316+ return -1;
1317+ }
1318+ ext4fs_indir3_blkno =
1319+ __le32_to_cpu(ext4fs_indir2_block[(rblock /
1320+ perblock_child) %
1321+ (blksz /
1322+ 4)]) <<
1323+ log2_blksz;
1324+ }
1325+
1326+ blknr = __le32_to_cpu(ext4fs_indir3_block
1327+ [rblock % perblock_child]);
1328+ }
1329+ debug("ext4fs_read_block %ld\n", blknr);
1330+
1331+ return blknr;
1332+}
1333+
1334+void ext4fs_close(void)
1335+{
1336+ if ((ext4fs_file != NULL) && (ext4fs_root != NULL)) {
1337+ ext4fs_free_node(ext4fs_file, &ext4fs_root->diropen);
1338+ ext4fs_file = NULL;
1339+ }
1340+ if (ext4fs_root != NULL) {
1341+ free(ext4fs_root);
1342+ ext4fs_root = NULL;
1343+ }
1344+ if (ext4fs_indir1_block != NULL) {
1345+ free(ext4fs_indir1_block);
1346+ ext4fs_indir1_block = NULL;
1347+ ext4fs_indir1_size = 0;
1348+ ext4fs_indir1_blkno = -1;
1349+ }
1350+ if (ext4fs_indir2_block != NULL) {
1351+ free(ext4fs_indir2_block);
1352+ ext4fs_indir2_block = NULL;
1353+ ext4fs_indir2_size = 0;
1354+ ext4fs_indir2_blkno = -1;
1355+ }
1356+ if (ext4fs_indir3_block != NULL) {
1357+ free(ext4fs_indir3_block);
1358+ ext4fs_indir3_block = NULL;
1359+ ext4fs_indir3_size = 0;
1360+ ext4fs_indir3_blkno = -1;
1361+ }
1362+}
1363+
1364+int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name,
1365+ struct ext2fs_node **fnode, int *ftype)
1366+{
1367+ unsigned int fpos = 0;
1368+ int status;
1369+ struct ext2fs_node *diro = (struct ext2fs_node *)dir;
1370+
1371+#ifdef DEBUG
1372+ if (name != NULL)
1373+ printf("Iterate dir %s\n", name);
1374+#endif /* of DEBUG */
1375+ if (!diro->inode_read) {
1376+ status = ext4fs_read_inode(diro->data, diro->ino, &diro->inode);
1377+ if (status == 0)
1378+ return 0;
1379+ }
1380+ /* Search the file. */
1381+ while (fpos < __le32_to_cpu(diro->inode.size)) {
1382+ struct ext2_dirent dirent;
1383+
1384+ status = ext4fs_read_file(diro, fpos,
1385+ sizeof(struct ext2_dirent),
1386+ (char *)&dirent);
1387+ if (status < 1)
1388+ return 0;
1389+
1390+ if (dirent.namelen != 0) {
1391+ char filename[dirent.namelen + 1];
1392+ struct ext2fs_node *fdiro;
1393+ int type = FILETYPE_UNKNOWN;
1394+
1395+ status = ext4fs_read_file(diro,
1396+ fpos +
1397+ sizeof(struct ext2_dirent),
1398+ dirent.namelen, filename);
1399+ if (status < 1)
1400+ return 0;
1401+
1402+ fdiro = zalloc(sizeof(struct ext2fs_node));
1403+ if (!fdiro)
1404+ return 0;
1405+
1406+ fdiro->data = diro->data;
1407+ fdiro->ino = __le32_to_cpu(dirent.inode);
1408+
1409+ filename[dirent.namelen] = '\0';
1410+
1411+ if (dirent.filetype != FILETYPE_UNKNOWN) {
1412+ fdiro->inode_read = 0;
1413+
1414+ if (dirent.filetype == FILETYPE_DIRECTORY)
1415+ type = FILETYPE_DIRECTORY;
1416+ else if (dirent.filetype == FILETYPE_SYMLINK)
1417+ type = FILETYPE_SYMLINK;
1418+ else if (dirent.filetype == FILETYPE_REG)
1419+ type = FILETYPE_REG;
1420+ } else {
1421+ status = ext4fs_read_inode(diro->data,
1422+ __le32_to_cpu
1423+ (dirent.inode),
1424+ &fdiro->inode);
1425+ if (status == 0) {
1426+ free(fdiro);
1427+ return 0;
1428+ }
1429+ fdiro->inode_read = 1;
1430+
1431+ if ((__le16_to_cpu(fdiro->inode.mode) &
1432+ FILETYPE_INO_MASK) ==
1433+ FILETYPE_INO_DIRECTORY) {
1434+ type = FILETYPE_DIRECTORY;
1435+ } else if ((__le16_to_cpu(fdiro->inode.mode)
1436+ & FILETYPE_INO_MASK) ==
1437+ FILETYPE_INO_SYMLINK) {
1438+ type = FILETYPE_SYMLINK;
1439+ } else if ((__le16_to_cpu(fdiro->inode.mode)
1440+ & FILETYPE_INO_MASK) ==
1441+ FILETYPE_INO_REG) {
1442+ type = FILETYPE_REG;
1443+ }
1444+ }
1445+#ifdef DEBUG
1446+ printf("iterate >%s<\n", filename);
1447+#endif /* of DEBUG */
1448+ if ((name != NULL) && (fnode != NULL)
1449+ && (ftype != NULL)) {
1450+ if (strcmp(filename, name) == 0) {
1451+ *ftype = type;
1452+ *fnode = fdiro;
1453+ return 1;
1454+ }
1455+ } else {
1456+ if (fdiro->inode_read == 0) {
1457+ status = ext4fs_read_inode(diro->data,
1458+ __le32_to_cpu(
1459+ dirent.inode),
1460+ &fdiro->inode);
1461+ if (status == 0) {
1462+ free(fdiro);
1463+ return 0;
1464+ }
1465+ fdiro->inode_read = 1;
1466+ }
1467+ switch (type) {
1468+ case FILETYPE_DIRECTORY:
1469+ printf("<DIR> ");
1470+ break;
1471+ case FILETYPE_SYMLINK:
1472+ printf("<SYM> ");
1473+ break;
1474+ case FILETYPE_REG:
1475+ printf(" ");
1476+ break;
1477+ default:
1478+ printf("< ? > ");
1479+ break;
1480+ }
1481+ printf("%10d %s\n",
1482+ __le32_to_cpu(fdiro->inode.size),
1483+ filename);
1484+ }
1485+ free(fdiro);
1486+ }
1487+ fpos += __le16_to_cpu(dirent.direntlen);
1488+ }
1489+ return 0;
1490+}
1491+
1492+static char *ext4fs_read_symlink(struct ext2fs_node *node)
1493+{
1494+ char *symlink;
1495+ struct ext2fs_node *diro = node;
1496+ int status;
1497+
1498+ if (!diro->inode_read) {
1499+ status = ext4fs_read_inode(diro->data, diro->ino, &diro->inode);
1500+ if (status == 0)
1501+ return 0;
1502+ }
1503+ symlink = zalloc(__le32_to_cpu(diro->inode.size) + 1);
1504+ if (!symlink)
1505+ return 0;
1506+
1507+ if (__le32_to_cpu(diro->inode.size) <= 60) {
1508+ strncpy(symlink, diro->inode.b.symlink,
1509+ __le32_to_cpu(diro->inode.size));
1510+ } else {
1511+ status = ext4fs_read_file(diro, 0,
1512+ __le32_to_cpu(diro->inode.size),
1513+ symlink);
1514+ if (status == 0) {
1515+ free(symlink);
1516+ return 0;
1517+ }
1518+ }
1519+ symlink[__le32_to_cpu(diro->inode.size)] = '\0';
1520+ return symlink;
1521+}
1522+
1523+static int ext4fs_find_file1(const char *currpath,
1524+ struct ext2fs_node *currroot,
1525+ struct ext2fs_node **currfound, int *foundtype)
1526+{
1527+ char fpath[strlen(currpath) + 1];
1528+ char *name = fpath;
1529+ char *next;
1530+ int status;
1531+ int type = FILETYPE_DIRECTORY;
1532+ struct ext2fs_node *currnode = currroot;
1533+ struct ext2fs_node *oldnode = currroot;
1534+
1535+ strncpy(fpath, currpath, strlen(currpath) + 1);
1536+
1537+ /* Remove all leading slashes. */
1538+ while (*name == '/')
1539+ name++;
1540+
1541+ if (!*name) {
1542+ *currfound = currnode;
1543+ return 1;
1544+ }
1545+
1546+ for (;;) {
1547+ int found;
1548+
1549+ /* Extract the actual part from the pathname. */
1550+ next = strchr(name, '/');
1551+ if (next) {
1552+ /* Remove all leading slashes. */
1553+ while (*next == '/')
1554+ *(next++) = '\0';
1555+ }
1556+
1557+ if (type != FILETYPE_DIRECTORY) {
1558+ ext4fs_free_node(currnode, currroot);
1559+ return 0;
1560+ }
1561+
1562+ oldnode = currnode;
1563+
1564+ /* Iterate over the directory. */
1565+ found = ext4fs_iterate_dir(currnode, name, &currnode, &type);
1566+ if (found == 0)
1567+ return 0;
1568+
1569+ if (found == -1)
1570+ break;
1571+
1572+ /* Read in the symlink and follow it. */
1573+ if (type == FILETYPE_SYMLINK) {
1574+ char *symlink;
1575+
1576+ /* Test if the symlink does not loop. */
1577+ if (++symlinknest == 8) {
1578+ ext4fs_free_node(currnode, currroot);
1579+ ext4fs_free_node(oldnode, currroot);
1580+ return 0;
1581+ }
1582+
1583+ symlink = ext4fs_read_symlink(currnode);
1584+ ext4fs_free_node(currnode, currroot);
1585+
1586+ if (!symlink) {
1587+ ext4fs_free_node(oldnode, currroot);
1588+ return 0;
1589+ }
1590+
1591+ debug("Got symlink >%s<\n", symlink);
1592+
1593+ if (symlink[0] == '/') {
1594+ ext4fs_free_node(oldnode, currroot);
1595+ oldnode = &ext4fs_root->diropen;
1596+ }
1597+
1598+ /* Lookup the node the symlink points to. */
1599+ status = ext4fs_find_file1(symlink, oldnode,
1600+ &currnode, &type);
1601+
1602+ free(symlink);
1603+
1604+ if (status == 0) {
1605+ ext4fs_free_node(oldnode, currroot);
1606+ return 0;
1607+ }
1608+ }
1609+
1610+ ext4fs_free_node(oldnode, currroot);
1611+
1612+ /* Found the node! */
1613+ if (!next || *next == '\0') {
1614+ *currfound = currnode;
1615+ *foundtype = type;
1616+ return 1;
1617+ }
1618+ name = next;
1619+ }
1620+ return -1;
1621+}
1622+
1623+int ext4fs_find_file(const char *path, struct ext2fs_node *rootnode,
1624+ struct ext2fs_node **foundnode, int expecttype)
1625+{
1626+ int status;
1627+ int foundtype = FILETYPE_DIRECTORY;
1628+
1629+ symlinknest = 0;
1630+ if (!path)
1631+ return 0;
1632+
1633+ status = ext4fs_find_file1(path, rootnode, foundnode, &foundtype);
1634+ if (status == 0)
1635+ return 0;
1636+
1637+ /* Check if the node that was found was of the expected type. */
1638+ if ((expecttype == FILETYPE_REG) && (foundtype != expecttype))
1639+ return 0;
1640+ else if ((expecttype == FILETYPE_DIRECTORY)
1641+ && (foundtype != expecttype))
1642+ return 0;
1643+
1644+ return 1;
1645+}
1646+
1647+int ext4fs_open(const char *filename)
1648+{
1649+ struct ext2fs_node *fdiro = NULL;
1650+ int status;
1651+ int len;
1652+
1653+ if (ext4fs_root == NULL)
1654+ return -1;
1655+
1656+ ext4fs_file = NULL;
1657+ status = ext4fs_find_file(filename, &ext4fs_root->diropen, &fdiro,
1658+ FILETYPE_REG);
1659+ if (status == 0)
1660+ goto fail;
1661+
1662+ if (!fdiro->inode_read) {
1663+ status = ext4fs_read_inode(fdiro->data, fdiro->ino,
1664+ &fdiro->inode);
1665+ if (status == 0)
1666+ goto fail;
1667+ }
1668+ len = __le32_to_cpu(fdiro->inode.size);
1669+ ext4fs_file = fdiro;
1670+
1671+ return len;
1672+ fail:
1673+ ext4fs_free_node(fdiro, &ext4fs_root->diropen);
1674+
1675+ return -1;
1676+}
1677+
1678+int ext4fs_mount(unsigned part_length)
1679+{
1680+ struct ext2_data *data;
1681+ int status;
1682+ struct ext_filesystem *fs = get_fs();
1683+ data = zalloc(sizeof(struct ext2_data));
1684+ if (!data)
1685+ return 0;
1686+
1687+ /* Read the superblock. */
1688+ status = ext4fs_devread(1 * 2, 0, sizeof(struct ext2_sblock),
1689+ (char *)&data->sblock);
1690+
1691+ if (status == 0)
1692+ goto fail;
1693+
1694+ /* Make sure this is an ext2 filesystem. */
1695+ if (__le16_to_cpu(data->sblock.magic) != EXT2_MAGIC)
1696+ goto fail;
1697+
1698+ if (__le32_to_cpu(data->sblock.revision_level == 0))
1699+ fs->inodesz = 128;
1700+ else
1701+ fs->inodesz = __le16_to_cpu(data->sblock.inode_size);
1702+
1703+ debug("EXT2 rev %d, inode_size %d\n",
1704+ __le32_to_cpu(data->sblock.revision_level), fs->inodesz);
1705+
1706+ data->diropen.data = data;
1707+ data->diropen.ino = 2;
1708+ data->diropen.inode_read = 1;
1709+ data->inode = &data->diropen.inode;
1710+
1711+ status = ext4fs_read_inode(data, 2, data->inode);
1712+ if (status == 0)
1713+ goto fail;
1714+
1715+ ext4fs_root = data;
1716+
1717+ return 1;
1718+ fail:
1719+ printf("Failed to mount ext2 filesystem...\n");
1720+ free(data);
1721+ ext4fs_root = NULL;
1722+
1723+ return 0;
1724+}
1725diff --git a/fs/ext4/ext4_common.h b/fs/ext4/ext4_common.h
1726new file mode 100644
1727index 0000000..18e6ad1
1728--- /dev/null
1729+++ b/fs/ext4/ext4_common.h
1730@@ -0,0 +1,63 @@
1731+/*
1732+ * (C) Copyright 2011 - 2012 Samsung Electronics
1733+ * EXT4 filesystem implementation in Uboot by
1734+ * Uma Shankar <uma.shankar@samsung.com>
1735+ * Manjunatha C Achar <a.manjunatha@samsung.com>
1736+ *
1737+ * ext4ls and ext4load : based on ext2 ls load support in Uboot.
1738+ *
1739+ * (C) Copyright 2004
1740+ * esd gmbh <www.esd-electronics.com>
1741+ * Reinhard Arlt <reinhard.arlt@esd-electronics.com>
1742+ *
1743+ * based on code from grub2 fs/ext2.c and fs/fshelp.c by
1744+ * GRUB -- GRand Unified Bootloader
1745+ * Copyright (C) 2003, 2004 Free Software Foundation, Inc.
1746+ *
1747+ * This program is free software; you can redistribute it and/or modify
1748+ * it under the terms of the GNU General Public License as published by
1749+ * the Free Software Foundation; either version 2 of the License, or
1750+ * (at your option) any later version.
1751+ *
1752+ * This program is distributed in the hope that it will be useful,
1753+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1754+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1755+ * GNU General Public License for more details.
1756+ *
1757+ * You should have received a copy of the GNU General Public License
1758+ * along with this program; if not, write to the Free Software
1759+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1760+ */
1761+
1762+#ifndef __EXT4_COMMON__
1763+#define __EXT4_COMMON__
1764+#include <ext_common.h>
1765+#include <ext4fs.h>
1766+#include <malloc.h>
1767+#include <asm/errno.h>
1768+
1769+#define YES 1
1770+#define NO 0
1771+#define TRUE 1
1772+#define FALSE 0
1773+#define RECOVER 1
1774+#define SCAN 0
1775+
1776+#define S_IFLNK 0120000 /* symbolic link */
1777+#define BLOCK_NO_ONE 1
1778+#define SUPERBLOCK_SECTOR 2
1779+#define SUPERBLOCK_SIZE 1024
1780+#define F_FILE 1
1781+
1782+#define zalloc(size) calloc(1, size)
1783+
1784+extern unsigned long part_offset;
1785+int ext4fs_read_inode(struct ext2_data *data, int ino,
1786+ struct ext2_inode *inode);
1787+int ext4fs_read_file(struct ext2fs_node *node, int pos,
1788+ unsigned int len, char *buf);
1789+int ext4fs_find_file(const char *path, struct ext2fs_node *rootnode,
1790+ struct ext2fs_node **foundnode, int expecttype);
1791+int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name,
1792+ struct ext2fs_node **fnode, int *ftype);
1793+#endif
1794diff --git a/fs/ext4/ext4fs.c b/fs/ext4/ext4fs.c
1795new file mode 100644
1796index 0000000..7933769
1797--- /dev/null
1798+++ b/fs/ext4/ext4fs.c
1799@@ -0,0 +1,228 @@
1800+/*
1801+ * (C) Copyright 2011 - 2012 Samsung Electronics
1802+ * EXT4 filesystem implementation in Uboot by
1803+ * Uma Shankar <uma.shankar@samsung.com>
1804+ * Manjunatha C Achar <a.manjunatha@samsung.com>
1805+ *
1806+ * ext4ls and ext4load : Based on ext2 ls and load support in Uboot.
1807+ * Ext4 read optimization taken from Open-Moko
1808+ * Qi bootloader
1809+ *
1810+ * (C) Copyright 2004
1811+ * esd gmbh <www.esd-electronics.com>
1812+ * Reinhard Arlt <reinhard.arlt@esd-electronics.com>
1813+ *
1814+ * based on code from grub2 fs/ext2.c and fs/fshelp.c by
1815+ * GRUB -- GRand Unified Bootloader
1816+ * Copyright (C) 2003, 2004 Free Software Foundation, Inc.
1817+ *
1818+ * This program is free software; you can redistribute it and/or modify
1819+ * it under the terms of the GNU General Public License as published by
1820+ * the Free Software Foundation; either version 2 of the License, or
1821+ * (at your option) any later version.
1822+ *
1823+ * This program is distributed in the hope that it will be useful,
1824+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1825+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1826+ * GNU General Public License for more details.
1827+ *
1828+ * You should have received a copy of the GNU General Public License
1829+ * along with this program; if not, write to the Free Software
1830+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
1831+ */
1832+
1833+#include <common.h>
1834+#include <malloc.h>
1835+#include <ext_common.h>
1836+#include <ext4fs.h>
1837+#include <linux/stat.h>
1838+#include <linux/time.h>
1839+#include <asm/byteorder.h>
1840+#include "ext4_common.h"
1841+
1842+int ext4fs_symlinknest;
1843+block_dev_desc_t *ext4_dev_desc;
1844+
1845+struct ext_filesystem *get_fs(void)
1846+{
1847+ if (ext4_dev_desc == NULL || ext4_dev_desc->priv == NULL)
1848+ printf("Invalid Input Arguments %s\n", __func__);
1849+
1850+ return ext4_dev_desc->priv;
1851+}
1852+
1853+int init_fs(block_dev_desc_t *dev_desc)
1854+{
1855+ struct ext_filesystem *fs;
1856+ if (dev_desc == NULL) {
1857+ printf("Invalid Input Arguments %s\n", __func__);
1858+ return -EINVAL;
1859+ }
1860+
1861+ fs = zalloc(sizeof(struct ext_filesystem));
1862+ if (fs == NULL) {
1863+ printf("malloc failed: %s\n", __func__);
1864+ return -ENOMEM;
1865+ }
1866+
1867+ fs->dev_desc = dev_desc;
1868+ dev_desc->priv = fs;
1869+
1870+ return 0;
1871+}
1872+
1873+void deinit_fs(block_dev_desc_t *dev_desc)
1874+{
1875+ if (dev_desc == NULL) {
1876+ printf("Invalid Input Arguments %s\n", __func__);
1877+ return;
1878+ }
1879+ free(dev_desc->priv);
1880+ dev_desc->priv = NULL;
1881+}
1882+
1883+void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot)
1884+{
1885+ if ((node != &ext4fs_root->diropen) && (node != currroot))
1886+ free(node);
1887+}
1888+
1889+/*
1890+ * Taken from openmoko-kernel mailing list: By Andy green
1891+ * Optimized read file API : collects and defers contiguous sector
1892+ * reads into one potentially more efficient larger sequential read action
1893+ */
1894+int ext4fs_read_file(struct ext2fs_node *node, int pos,
1895+ unsigned int len, char *buf)
1896+{
1897+ int i;
1898+ int blockcnt;
1899+ int log2blocksize = LOG2_EXT2_BLOCK_SIZE(node->data);
1900+ int blocksize = 1 << (log2blocksize + DISK_SECTOR_BITS);
1901+ unsigned int filesize = __le32_to_cpu(node->inode.size);
1902+ int previous_block_number = -1;
1903+ int delayed_start = 0;
1904+ int delayed_extent = 0;
1905+ int delayed_skipfirst = 0;
1906+ int delayed_next = 0;
1907+ char *delayed_buf = NULL;
1908+ short status;
1909+
1910+ /* Adjust len so it we can't read past the end of the file. */
1911+ if (len > filesize)
1912+ len = filesize;
1913+
1914+ blockcnt = ((len + pos) + blocksize - 1) / blocksize;
1915+
1916+ for (i = pos / blocksize; i < blockcnt; i++) {
1917+ int blknr;
1918+ int blockoff = pos % blocksize;
1919+ int blockend = blocksize;
1920+ int skipfirst = 0;
1921+ blknr = read_allocated_block(&(node->inode), i);
1922+ if (blknr < 0)
1923+ return -1;
1924+
1925+ blknr = blknr << log2blocksize;
1926+
1927+ /* Last block. */
1928+ if (i == blockcnt - 1) {
1929+ blockend = (len + pos) % blocksize;
1930+
1931+ /* The last portion is exactly blocksize. */
1932+ if (!blockend)
1933+ blockend = blocksize;
1934+ }
1935+
1936+ /* First block. */
1937+ if (i == pos / blocksize) {
1938+ skipfirst = blockoff;
1939+ blockend -= skipfirst;
1940+ }
1941+ if (blknr) {
1942+ int status;
1943+
1944+ if (previous_block_number != -1) {
1945+ if (delayed_next == blknr) {
1946+ delayed_extent += blockend;
1947+ delayed_next += blockend >> SECTOR_BITS;
1948+ } else { /* spill */
1949+ status = ext4fs_devread(delayed_start,
1950+ delayed_skipfirst,
1951+ delayed_extent,
1952+ delayed_buf);
1953+ if (status == 0)
1954+ return -1;
1955+ previous_block_number = blknr;
1956+ delayed_start = blknr;
1957+ delayed_extent = blockend;
1958+ delayed_skipfirst = skipfirst;
1959+ delayed_buf = buf;
1960+ delayed_next = blknr +
1961+ (blockend >> SECTOR_BITS);
1962+ }
1963+ } else {
1964+ previous_block_number = blknr;
1965+ delayed_start = blknr;
1966+ delayed_extent = blockend;
1967+ delayed_skipfirst = skipfirst;
1968+ delayed_buf = buf;
1969+ delayed_next = blknr +
1970+ (blockend >> SECTOR_BITS);
1971+ }
1972+ } else {
1973+ if (previous_block_number != -1) {
1974+ /* spill */
1975+ status = ext4fs_devread(delayed_start,
1976+ delayed_skipfirst,
1977+ delayed_extent,
1978+ delayed_buf);
1979+ if (status == 0)
1980+ return -1;
1981+ previous_block_number = -1;
1982+ }
1983+ memset(buf, 0, blocksize - skipfirst);
1984+ }
1985+ buf += blocksize - skipfirst;
1986+ }
1987+ if (previous_block_number != -1) {
1988+ /* spill */
1989+ status = ext4fs_devread(delayed_start,
1990+ delayed_skipfirst, delayed_extent,
1991+ delayed_buf);
1992+ if (status == 0)
1993+ return -1;
1994+ previous_block_number = -1;
1995+ }
1996+
1997+ return len;
1998+}
1999+
2000+int ext4fs_ls(const char *dirname)
2001+{
2002+ struct ext2fs_node *dirnode;
2003+ int status;
2004+
2005+ if (dirname == NULL)
2006+ return 0;
2007+
2008+ status = ext4fs_find_file(dirname, &ext4fs_root->diropen, &dirnode,
2009+ FILETYPE_DIRECTORY);
2010+ if (status != 1) {
2011+ printf("** Can not find directory. **\n");
2012+ return 1;
2013+ }
2014+
2015+ ext4fs_iterate_dir(dirnode, NULL, NULL, NULL);
2016+ ext4fs_free_node(dirnode, &ext4fs_root->diropen);
2017+
2018+ return 0;
2019+}
2020+
2021+int ext4fs_read(char *buf, unsigned len)
2022+{
2023+ if (ext4fs_root == NULL || ext4fs_file == NULL)
2024+ return 0;
2025+
2026+ return ext4fs_read_file(ext4fs_file, 0, len, buf);
2027+}
2028diff --git a/include/ext4fs.h b/include/ext4fs.h
2029new file mode 100644
2030index 0000000..58a6a1d
2031--- /dev/null
2032+++ b/include/ext4fs.h
2033@@ -0,0 +1,132 @@
2034+/*
2035+ * (C) Copyright 2011 - 2012 Samsung Electronics
2036+ * EXT4 filesystem implementation in Uboot by
2037+ * Uma Shankar <uma.shankar@samsung.com>
2038+ * Manjunatha C Achar <a.manjunatha@samsung.com>
2039+ *
2040+ * Ext4 Extent data structures are taken from original ext4 fs code
2041+ * as found in the linux kernel.
2042+ *
2043+ * Copyright (c) 2003-2006, Cluster File Systems, Inc, info@clusterfs.com
2044+ * Written by Alex Tomas <alex@clusterfs.com>
2045+ *
2046+ * This program is free software; you can redistribute it and/or modify
2047+ * it under the terms of the GNU General Public License version 2 as
2048+ * published by the Free Software Foundation.
2049+ *
2050+ * This program is distributed in the hope that it will be useful,
2051+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2052+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2053+ * GNU General Public License for more details.
2054+ *
2055+ * You should have received a copy of the GNU General Public License
2056+ * along with this program; if not, write to the Free Software
2057+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2058+ */
2059+
2060+#ifndef __EXT4__
2061+#define __EXT4__
2062+#include <ext_common.h>
2063+
2064+#define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
2065+#define EXT4_EXT_MAGIC 0xf30a
2066+#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010
2067+#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040
2068+#define EXT4_INDIRECT_BLOCKS 12
2069+
2070+#define EXT4_BG_INODE_UNINIT 0x0001
2071+#define EXT4_BG_BLOCK_UNINIT 0x0002
2072+#define EXT4_BG_INODE_ZEROED 0x0004
2073+
2074+/*
2075+ * ext4_inode has i_block array (60 bytes total).
2076+ * The first 12 bytes store ext4_extent_header;
2077+ * the remainder stores an array of ext4_extent.
2078+ */
2079+
2080+/*
2081+ * This is the extent on-disk structure.
2082+ * It's used at the bottom of the tree.
2083+ */
2084+struct ext4_extent {
2085+ __le32 ee_block; /* first logical block extent covers */
2086+ __le16 ee_len; /* number of blocks covered by extent */
2087+ __le16 ee_start_hi; /* high 16 bits of physical block */
2088+ __le32 ee_start_lo; /* low 32 bits of physical block */
2089+};
2090+
2091+/*
2092+ * This is index on-disk structure.
2093+ * It's used at all the levels except the bottom.
2094+ */
2095+struct ext4_extent_idx {
2096+ __le32 ei_block; /* index covers logical blocks from 'block' */
2097+ __le32 ei_leaf_lo; /* pointer to the physical block of the next *
2098+ * level. leaf or next index could be there */
2099+ __le16 ei_leaf_hi; /* high 16 bits of physical block */
2100+ __u16 ei_unused;
2101+};
2102+
2103+/* Each block (leaves and indexes), even inode-stored has header. */
2104+struct ext4_extent_header {
2105+ __le16 eh_magic; /* probably will support different formats */
2106+ __le16 eh_entries; /* number of valid entries */
2107+ __le16 eh_max; /* capacity of store in entries */
2108+ __le16 eh_depth; /* has tree real underlying blocks? */
2109+ __le32 eh_generation; /* generation of the tree */
2110+};
2111+
2112+struct ext_filesystem {
2113+ /* Total Sector of partition */
2114+ uint64_t total_sect;
2115+ /* Block size of partition */
2116+ uint32_t blksz;
2117+ /* Inode size of partition */
2118+ uint32_t inodesz;
2119+ /* Sectors per Block */
2120+ uint32_t sect_perblk;
2121+ /* Group Descriptor Block Number */
2122+ uint32_t gdtable_blkno;
2123+ /* Total block groups of partition */
2124+ uint32_t no_blkgrp;
2125+ /* No of blocks required for bgdtable */
2126+ uint32_t no_blk_pergdt;
2127+ /* Superblock */
2128+ struct ext2_sblock *sb;
2129+ /* Block group descritpor table */
2130+ struct ext2_block_group *gd;
2131+ char *gdtable;
2132+
2133+ /* Block Bitmap Related */
2134+ unsigned char **blk_bmaps;
2135+ long int curr_blkno;
2136+ uint16_t first_pass_bbmap;
2137+
2138+ /* Inode Bitmap Related */
2139+ unsigned char **inode_bmaps;
2140+ int curr_inode_no;
2141+ uint16_t first_pass_ibmap;
2142+
2143+ /* Journal Related */
2144+
2145+ /* Block Device Descriptor */
2146+ block_dev_desc_t *dev_desc;
2147+};
2148+
2149+extern block_dev_desc_t *ext4_dev_desc;
2150+extern struct ext2_data *ext4fs_root;
2151+extern struct ext2fs_node *ext4fs_file;
2152+
2153+struct ext_filesystem *get_fs(void);
2154+int init_fs(block_dev_desc_t *dev_desc);
2155+void deinit_fs(block_dev_desc_t *dev_desc);
2156+int ext4fs_open(const char *filename);
2157+int ext4fs_read(char *buf, unsigned len);
2158+int ext4fs_mount(unsigned part_length);
2159+void ext4fs_close(void);
2160+int ext4fs_ls(const char *dirname);
2161+void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot);
2162+int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf);
2163+int ext4fs_set_blk_dev(block_dev_desc_t *rbdd, int part);
2164+long int read_allocated_block(struct ext2_inode *inode, int fileblock);
2165+#endif
2166diff --git a/include/ext_common.h b/include/ext_common.h
2167new file mode 100644
2168index 0000000..5d48021
2169--- /dev/null
2170+++ b/include/ext_common.h
2171@@ -0,0 +1,188 @@
2172+/*
2173+ * (C) Copyright 2011 - 2012 Samsung Electronics
2174+ * EXT4 filesystem implementation in Uboot by
2175+ * Uma Shankar <uma.shankar@samsung.com>
2176+ * Manjunatha C Achar <a.manjunatha@samsung.com>
2177+ *
2178+ * Data structures and headers for ext4 support have been taken from
2179+ * ext2 ls load support in Uboot
2180+ *
2181+ * (C) Copyright 2004
2182+ * esd gmbh <www.esd-electronics.com>
2183+ * Reinhard Arlt <reinhard.arlt@esd-electronics.com>
2184+ *
2185+ * based on code from grub2 fs/ext2.c and fs/fshelp.c by
2186+ * GRUB -- GRand Unified Bootloader
2187+ * Copyright (C) 2003, 2004 Free Software Foundation, Inc.
2188+ *
2189+ * This program is free software; you can redistribute it and/or modify
2190+ * it under the terms of the GNU General Public License as published by
2191+ * the Free Software Foundation; either version 2 of the License, or
2192+ * (at your option) any later version.
2193+ *
2194+ * This program is distributed in the hope that it will be useful,
2195+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2196+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2197+ * GNU General Public License for more details.
2198+ *
2199+ * You should have received a copy of the GNU General Public License
2200+ * along with this program; if not, write to the Free Software
2201+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
2202+ */
2203+
2204+#ifndef __EXT_COMMON__
2205+#define __EXT_COMMON__
2206+
2207+#define SECTOR_SIZE 0x200
2208+#define SECTOR_BITS 9
2209+
2210+/* Magic value used to identify an ext2 filesystem. */
2211+#define EXT2_MAGIC 0xEF53
2212+/* Amount of indirect blocks in an inode. */
2213+#define INDIRECT_BLOCKS 12
2214+/* Maximum lenght of a pathname. */
2215+#define EXT2_PATH_MAX 4096
2216+/* Maximum nesting of symlinks, used to prevent a loop. */
2217+#define EXT2_MAX_SYMLINKCNT 8
2218+
2219+/* Filetype used in directory entry. */
2220+#define FILETYPE_UNKNOWN 0
2221+#define FILETYPE_REG 1
2222+#define FILETYPE_DIRECTORY 2
2223+#define FILETYPE_SYMLINK 7
2224+
2225+/* Filetype information as used in inodes. */
2226+#define FILETYPE_INO_MASK 0170000
2227+#define FILETYPE_INO_REG 0100000
2228+#define FILETYPE_INO_DIRECTORY 0040000
2229+#define FILETYPE_INO_SYMLINK 0120000
2230+#define EXT2_ROOT_INO 2 /* Root inode */
2231+
2232+/* Bits used as offset in sector */
2233+#define DISK_SECTOR_BITS 9
2234+/* The size of an ext2 block in bytes. */
2235+#define EXT2_BLOCK_SIZE(data) (1 << LOG2_BLOCK_SIZE(data))
2236+
2237+/* Log2 size of ext2 block in 512 blocks. */
2238+#define LOG2_EXT2_BLOCK_SIZE(data) (__le32_to_cpu \
2239+ (data->sblock.log2_block_size) + 1)
2240+
2241+/* Log2 size of ext2 block in bytes. */
2242+#define LOG2_BLOCK_SIZE(data) (__le32_to_cpu \
2243+ (data->sblock.log2_block_size) + 10)
2244+#define INODE_SIZE_FILESYSTEM(data) (__le32_to_cpu \
2245+ (data->sblock.inode_size))
2246+
2247+#define EXT2_FT_DIR 2
2248+#define SUCCESS 1
2249+
2250+/* Macro-instructions used to manage several block sizes */
2251+#define EXT2_MIN_BLOCK_LOG_SIZE 10 /* 1024 */
2252+#define EXT2_MAX_BLOCK_LOG_SIZE 16 /* 65536 */
2253+#define EXT2_MIN_BLOCK_SIZE (1 << EXT2_MIN_BLOCK_LOG_SIZE)
2254+#define EXT2_MAX_BLOCK_SIZE (1 << EXT2_MAX_BLOCK_LOG_SIZE)
2255+
2256+/* The ext2 superblock. */
2257+struct ext2_sblock {
2258+ uint32_t total_inodes;
2259+ uint32_t total_blocks;
2260+ uint32_t reserved_blocks;
2261+ uint32_t free_blocks;
2262+ uint32_t free_inodes;
2263+ uint32_t first_data_block;
2264+ uint32_t log2_block_size;
2265+ uint32_t log2_fragment_size;
2266+ uint32_t blocks_per_group;
2267+ uint32_t fragments_per_group;
2268+ uint32_t inodes_per_group;
2269+ uint32_t mtime;
2270+ uint32_t utime;
2271+ uint16_t mnt_count;
2272+ uint16_t max_mnt_count;
2273+ uint16_t magic;
2274+ uint16_t fs_state;
2275+ uint16_t error_handling;
2276+ uint16_t minor_revision_level;
2277+ uint32_t lastcheck;
2278+ uint32_t checkinterval;
2279+ uint32_t creator_os;
2280+ uint32_t revision_level;
2281+ uint16_t uid_reserved;
2282+ uint16_t gid_reserved;
2283+ uint32_t first_inode;
2284+ uint16_t inode_size;
2285+ uint16_t block_group_number;
2286+ uint32_t feature_compatibility;
2287+ uint32_t feature_incompat;
2288+ uint32_t feature_ro_compat;
2289+ uint32_t unique_id[4];
2290+ char volume_name[16];
2291+ char last_mounted_on[64];
2292+ uint32_t compression_info;
2293+};
2294+
2295+struct ext2_block_group {
2296+ __u32 block_id; /* Blocks bitmap block */
2297+ __u32 inode_id; /* Inodes bitmap block */
2298+ __u32 inode_table_id; /* Inodes table block */
2299+ __u16 free_blocks; /* Free blocks count */
2300+ __u16 free_inodes; /* Free inodes count */
2301+ __u16 used_dir_cnt; /* Directories count */
2302+ __u16 bg_flags;
2303+ __u32 bg_reserved[2];
2304+ __u16 bg_itable_unused; /* Unused inodes count */
2305+ __u16 bg_checksum; /* crc16(s_uuid+grouo_num+group_desc)*/
2306+};
2307+
2308+/* The ext2 inode. */
2309+struct ext2_inode {
2310+ uint16_t mode;
2311+ uint16_t uid;
2312+ uint32_t size;
2313+ uint32_t atime;
2314+ uint32_t ctime;
2315+ uint32_t mtime;
2316+ uint32_t dtime;
2317+ uint16_t gid;
2318+ uint16_t nlinks;
2319+ uint32_t blockcnt; /* Blocks of 512 bytes!! */
2320+ uint32_t flags;
2321+ uint32_t osd1;
2322+ union {
2323+ struct datablocks {
2324+ uint32_t dir_blocks[INDIRECT_BLOCKS];
2325+ uint32_t indir_block;
2326+ uint32_t double_indir_block;
2327+ uint32_t triple_indir_block;
2328+ } blocks;
2329+ char symlink[60];
2330+ } b;
2331+ uint32_t version;
2332+ uint32_t acl;
2333+ uint32_t dir_acl;
2334+ uint32_t fragment_addr;
2335+ uint32_t osd2[3];
2336+};
2337+
2338+/* The header of an ext2 directory entry. */
2339+struct ext2_dirent {
2340+ uint32_t inode;
2341+ uint16_t direntlen;
2342+ uint8_t namelen;
2343+ uint8_t filetype;
2344+};
2345+
2346+struct ext2fs_node {
2347+ struct ext2_data *data;
2348+ struct ext2_inode inode;
2349+ int ino;
2350+ int inode_read;
2351+};
2352+
2353+/* Information about a "mounted" ext2 filesystem. */
2354+struct ext2_data {
2355+ struct ext2_sblock sblock;
2356+ struct ext2_inode *inode;
2357+ struct ext2fs_node diropen;
2358+};
2359+#endif
2360--
23611.7.10
2362
diff --git a/recipes-bsp/u-boot/u-boot/2011.12/0013-beagleboard-switch-mmcroots-to-ext4.patch b/recipes-bsp/u-boot/u-boot/2011.12/0013-beagleboard-switch-mmcroots-to-ext4.patch
new file mode 100644
index 00000000..c80dfc2b
--- /dev/null
+++ b/recipes-bsp/u-boot/u-boot/2011.12/0013-beagleboard-switch-mmcroots-to-ext4.patch
@@ -0,0 +1,43 @@
1From f5b19d6609a540a9eafa60dad902e7416df57771 Mon Sep 17 00:00:00 2001
2From: Koen Kooi <koen@dominion.thruhere.net>
3Date: Mon, 30 Apr 2012 11:10:07 +0200
4Subject: [PATCH 13/13] beagleboard: switch mmcroots to ext4
5
6Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
7---
8 include/configs/omap3_beagle.h | 5 +++--
9 1 file changed, 3 insertions(+), 2 deletions(-)
10
11diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h
12index 65ab8ee..3157d47 100644
13--- a/include/configs/omap3_beagle.h
14+++ b/include/configs/omap3_beagle.h
15@@ -140,6 +140,7 @@
16
17 #define CONFIG_CMD_CACHE
18 #define CONFIG_CMD_EXT2 /* EXT2 Support */
19+#define CONFIG_CMD_EXT4
20 #define CONFIG_CMD_FAT /* FAT support */
21 #define CONFIG_CMD_JFFS2 /* JFFS2 Support */
22 #define CONFIG_CMD_MTDPARTS /* Enable MTD parts commands */
23@@ -222,7 +223,7 @@
24 "defaultdisplay=dvi\0" \
25 "mmcdev=0\0" \
26 "mmcroot=/dev/mmcblk0p2 ro\0" \
27- "mmcrootfstype=ext3 rootwait\0" \
28+ "mmcrootfstype=ext4 rootwait\0" \
29 "nandroot=ubi0:rootfs ubi.mtd=4\0" \
30 "nandrootfstype=ubifs\0" \
31 "ramroot=/dev/ram0 rw ramdisk_size=65536 initrd=0x81000000,64M\0" \
32@@ -265,7 +266,7 @@
33 "rootfstype=${ramrootfstype}\0" \
34 "loadramdisk=fatload mmc ${mmcdev} ${rdaddr} ramdisk.gz\0" \
35 "loaduimagefat=fatload mmc ${mmcdev} ${loadaddr} uImage\0" \
36- "loaduimage=ext2load mmc ${mmcdev}:2 ${loadaddr} /boot/uImage\0" \
37+ "loaduimage=ext4load mmc ${mmcdev}:2 ${loadaddr} /boot/uImage\0" \
38 "mmcboot=echo Booting from mmc ...; " \
39 "run mmcargs; " \
40 "bootm ${loadaddr}\0" \
41--
421.7.10
43
diff --git a/recipes-bsp/u-boot/u-boot_2011.12.bb b/recipes-bsp/u-boot/u-boot_2011.12.bb
index 9616a053..45c64a68 100644
--- a/recipes-bsp/u-boot/u-boot_2011.12.bb
+++ b/recipes-bsp/u-boot/u-boot_2011.12.bb
@@ -6,7 +6,7 @@ UBOOT_IMAGE = "u-boot-${MACHINE}-${PV}-${PR}.img"
6UBOOT_SYMLINK = "u-boot-${MACHINE}.img" 6UBOOT_SYMLINK = "u-boot-${MACHINE}.img"
7 7
8PV = "2011.12" 8PV = "2011.12"
9PR = "r7" 9PR = "r8"
10 10
11# No patches for other machines yet 11# No patches for other machines yet
12COMPATIBLE_MACHINE = "(beagleboard|pandaboard|hawkboard|am3517-evm|am37x-evm|omap3evm)" 12COMPATIBLE_MACHINE = "(beagleboard|pandaboard|hawkboard|am3517-evm|am37x-evm|omap3evm)"
@@ -30,6 +30,9 @@ SRC_URI = "git://www.denx.de/git/u-boot.git;protocol=git \
30 ${CACHEFIX} \ 30 ${CACHEFIX} \
31 file://2011.12/0009-Beagleboard-Correct-memory-size-on-rev-C4.patch \ 31 file://2011.12/0009-Beagleboard-Correct-memory-size-on-rev-C4.patch \
32 file://2011.12/0010-OMAP3-Correct-get_sdr_cs_offset-mask.patch \ 32 file://2011.12/0010-OMAP3-Correct-get_sdr_cs_offset-mask.patch \
33 file://2011.12/0011-ext2load-increase-read-speed.patch \
34 file://2011.12/0012-ext4fs-ls-load-support.patch \
35 file://2011.12/0013-beagleboard-switch-mmcroots-to-ext4.patch \
33 ${FWENV} \ 36 ${FWENV} \
34 " 37 "
35 38