
cmd_ext2dm.c is a copy of cmd_ext2.c with just trivial changes, but those touch large portion of the lines due to different number of parameters (old API has a separate parameter for interface and for disk number, new API has this as one)
Signed-off-by: Pavel Herrmann morpheus.ibis@gmail.com --- common/Makefile | 3 +- common/cmd_ext2dm.c | 211 ++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/ext2/Makefile | 7 +- fs/ext2/dev_dm.c | 107 ++++++++++++++++++++++++++ include/ext2fs.h | 9 ++- 5 files changed, 334 insertions(+), 3 deletions(-) create mode 100644 common/cmd_ext2dm.c create mode 100644 fs/ext2/dev_dm.c
diff --git a/common/Makefile b/common/Makefile index 29e5798..22f9234 100644 --- a/common/Makefile +++ b/common/Makefile @@ -87,10 +87,11 @@ COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += cmd_eeprom.o COBJS-$(CONFIG_CMD_EEPROM) += cmd_eeprom.o COBJS-$(CONFIG_CMD_ELF) += cmd_elf.o COBJS-$(CONFIG_SYS_HUSH_PARSER) += cmd_exit.o -COBJS-$(CONFIG_CMD_EXT2) += cmd_ext2.o ifdef CONFIG_DM +COBJS-$(CONFIG_CMD_EXT2) += cmd_ext2dm.o COBJS-$(CONFIG_CMD_FAT) += cmd_fatdm.o else +COBJS-$(CONFIG_CMD_EXT2) += cmd_ext2.o COBJS-$(CONFIG_CMD_FAT) += cmd_fat.o endif COBJS-$(CONFIG_CMD_FDC)$(CONFIG_CMD_FDOS) += cmd_fdc.o diff --git a/common/cmd_ext2dm.c b/common/cmd_ext2dm.c new file mode 100644 index 0000000..da703eb --- /dev/null +++ b/common/cmd_ext2dm.c @@ -0,0 +1,211 @@ +/* + * (C) Copyright 2004 + * esd gmbh <www.esd-electronics.com> + * Reinhard Arlt reinhard.arlt@esd-electronics.com + * + * made from cmd_reiserfs by + * + * (C) Copyright 2003 - 2004 + * Sysgo Real-Time Solutions, AG <www.elinos.com> + * Pavel Bartusek pba@sysgo.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +/* + * Ext2fs support + */ +#include <common.h> +#include <config.h> +#include <command.h> +#include <image.h> +#include <linux/ctype.h> +#include <asm/byteorder.h> +#include <ext2fs.h> +#include <dm/structures.h> +#include <dm/blockdev.h> + +/* #define EXT2_DEBUG */ + +#ifdef EXT2_DEBUG +#define PRINTF(fmt, args...) printf(fmt, ##args) +#else +#define PRINTF(fmt, args...) +#endif + +int do_ext2ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + char *filename = "/"; + struct instance *bdev; + int part_length; + + if (argc < 2) + return CMD_RET_USAGE; + + bdev = get_blockdev_by_name(argv[1]); + + if (bdev == NULL) { + printf("\n** Block device %s not found\n", argv[1]); + return 1; + } + + if (argc == 3) + filename = argv[2]; + + PRINTF("Using device %s, directory: %s\n", argv[1], filename); + + part_length = ext2fs_set_blk_dev(bdev); + if (part_length == 0) { + printf("** Bad partition - %s **\n", argv[1]); + ext2fs_close(); + return 1; + } + + if (!ext2fs_mount(part_length)) { + printf("** Bad ext2 partition or disk - %s**\n", argv[1]); + ext2fs_close(); + return 1; + } + + if (ext2fs_ls(filename)) { + printf("** Error ext2fs_ls() **\n"); + ext2fs_close(); + return 1; + }; + + ext2fs_close(); + + return 0; +} + +U_BOOT_CMD( + ext2ls, 3, 1, do_ext2ls, + "list files in a directory (default /)", + "<dev[:part]> [directory]\n" + " - list files from 'dev' in a 'directory'" +); + +/****************************************************************************** + * Ext2fs boot command intepreter. Derived from diskboot + */ +int do_ext2load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + char *filename = NULL; + struct instance *bdev; + ulong addr = 0, part_length; + int filelen; + char buf[12]; + unsigned long count; + char *addr_str; + + switch (argc) { + case 2: + addr_str = getenv("loadaddr"); + if (addr_str != NULL) + addr = simple_strtoul(addr_str, NULL, 16); + else + addr = CONFIG_SYS_LOAD_ADDR; + + filename = getenv("bootfile"); + count = 0; + break; + case 3: + addr = simple_strtoul(argv[2], NULL, 16); + filename = getenv("bootfile"); + count = 0; + break; + case 4: + addr = simple_strtoul(argv[2], NULL, 16); + filename = argv[3]; + count = 0; + break; + case 5: + addr = simple_strtoul(argv[2], NULL, 16); + filename = argv[3]; + count = simple_strtoul(argv[4], NULL, 16); + break; + + default: + return CMD_RET_USAGE; + } + + if (!filename) { + puts("** No boot file defined **\n"); + return 1; + } + + bdev = get_blockdev_by_name(argv[1]); + if (!bdev) { + printf("** Block device %s not found\n", argv[1]); + return 1; + } + + PRINTF("Using device %s\n", argv[1]); + + printf("Loading file "%s" from device %s\n", filename, argv[1]); + + part_length = ext2fs_set_blk_dev(bdev); + if (part_length == 0) { + printf("** Bad partition - %s **\n", argv[1]); + ext2fs_close(); + return 1; + } + + if (!ext2fs_mount(part_length)) { + printf("** Bad ext2 partition or disk - %s **\n", argv[1]); + ext2fs_close(); + return 1; + } + + filelen = ext2fs_open(filename); + if (filelen < 0) { + printf("** File not found %s\n", filename); + ext2fs_close(); + return 1; + } + if ((count < filelen) && (count != 0)) + filelen = count; + + if (ext2fs_read((char *)addr, filelen) != filelen) { + printf("** Unable to read "%s" from %s **\n", filename, + argv[1]); + ext2fs_close(); + return 1; + } + + ext2fs_close(); + + /* Loading ok, update default load address */ + load_addr = addr; + + printf("%d bytes read\n", filelen); + sprintf(buf, "%X", filelen); + setenv("filesize", buf); + + return 0; +} + +U_BOOT_CMD( + ext2load, 5, 0, do_ext2load, + "load binary file from a Ext2 filesystem", + "<dev[:part]> [addr] [filename] [bytes]\n" + " - load binary file 'filename' from 'dev'\n" + " to address 'addr' from ext2 filesystem" +); diff --git a/fs/ext2/Makefile b/fs/ext2/Makefile index 3c65d25..ac4ddf2 100644 --- a/fs/ext2/Makefile +++ b/fs/ext2/Makefile @@ -30,7 +30,12 @@ include $(TOPDIR)/config.mk LIB = $(obj)libext2fs.o
AOBJS = -COBJS-$(CONFIG_CMD_EXT2) := ext2fs.o dev.o +COBJS-$(CONFIG_CMD_EXT2) := ext2fs.o +ifdef CONFIG_DM +COBJS-${CONFIG_CMD_EXT2} += dev_dm.o +else +COBJS-${CONFIG_CMD_EXT2} += dev.o +endif
SRCS := $(AOBJS:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(AOBJS) $(COBJS-y)) diff --git a/fs/ext2/dev_dm.c b/fs/ext2/dev_dm.c new file mode 100644 index 0000000..6539b44 --- /dev/null +++ b/fs/ext2/dev_dm.c @@ -0,0 +1,107 @@ +/* + * (C) Copyright 2004 + * esd gmbh <www.esd-electronics.com> + * Reinhard Arlt reinhard.arlt@esd-electronics.com + * + * based on code of fs/reiserfs/dev.c by + * + * (C) Copyright 2003 - 2004 + * Sysgo AG, <www.elinos.com>, Pavel Bartusek pba@sysgo.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include <common.h> +#include <config.h> +#include <ext2fs.h> +#include <dm/structures.h> +#include <dm/blockdev.h> + +static struct instance *bdev; + +int ext2fs_set_blk_dev(struct instance *dev) +{ + struct option opt; + int error; + + if (!dev) + return 0; + + error = blockdev_get_option(dev, BLKD_OPT_BLOCKCOUNT, &opt); + if (error || (OPTION_TYPE(opt) != OPTION_TYPE_U)) + return 0; + + bdev = dev; + + return opt.data.data_u; +} + +int ext2fs_devread(int sector, int byte_offset, int byte_len, char *buf) +{ + ALLOC_CACHE_ALIGN_BUFFER(char, sec_buf, SECTOR_SIZE); + unsigned sectors; + + /* + * Get the read to the beginning of a partition. + */ + sector += byte_offset >> SECTOR_BITS; + byte_offset &= SECTOR_SIZE - 1; + + debug(" <%d, %d, %d>\n", sector, byte_offset, byte_len); + + if (bdev == NULL) { + printf(" ** %s Invalid Block Device Descriptor (NULL)\n", + __func__); + return 0; + } + + if (byte_offset != 0) { + /* read first part which isn't aligned with start of sector */ + if (blockdev_read(bdev, sector, 1, sec_buf) != 1) { + printf(" ** %s read error **\n", __func__); + return 0; + } + memcpy(buf, sec_buf + byte_offset, + min(SECTOR_SIZE - byte_offset, byte_len)); + buf += min(SECTOR_SIZE - byte_offset, byte_len); + byte_len -= min(SECTOR_SIZE - byte_offset, byte_len); + sector++; + } + + /* read sector aligned part */ + sectors = byte_len / SECTOR_SIZE; + + if (sectors > 0) { + if (blockdev_read(bdev, sector, sectors, buf) != sectors) { + printf(" ** %s read error - block\n", __func__); + return 0; + } + + buf += sectors * SECTOR_SIZE; + byte_len -= sectors * SECTOR_SIZE; + sector += sectors; + } + + if (byte_len != 0) { + /* read rest of data which are not in whole sector */ + if (blockdev_read(bdev, sector, 1, sec_buf) != 1) { + printf(" ** %s read error - last part\n", __func__); + return 0; + } + memcpy(buf, sec_buf, byte_len); + } + return 1; +} diff --git a/include/ext2fs.h b/include/ext2fs.h index 163a9bb..d16714e 100644 --- a/include/ext2fs.h +++ b/include/ext2fs.h @@ -25,6 +25,10 @@ * from the original ext2 fs code, as found in the linux kernel. */
+#ifdef CONFIG_DM +#include <dm/structures.h> +#endif +
#define SECTOR_SIZE 0x200 #define SECTOR_BITS 9 @@ -72,8 +76,11 @@ typedef enum MAX_ERR_NUM } ext2fs_error_t;
- +#ifdef CONFIG_DM +extern int ext2fs_set_blk_dev(struct instance *dev); +#else extern int ext2fs_set_blk_dev(block_dev_desc_t *rbdd, int part); +#endif extern int ext2fs_ls (const char *dirname); extern int ext2fs_open (const char *filename); extern int ext2fs_read (char *buf, unsigned len);