mirror of
https://github.com/u-boot/u-boot.git
synced 2024-11-24 04:34:22 +08:00
fs: add filesystem switch libary, implement ls and fsload commands
Implement "ls" and "fsload" commands that act like {fat,ext2}{ls,load}, and transparently handle either file-system. This scheme could easily be extended to other filesystem types; I only didn't do it for zfs because I don't have any filesystems of that type to test with. Replace the implementation of {fat,ext[24]}{ls,load} with this new code too. Signed-off-by: Stephen Warren <swarren@nvidia.com>
This commit is contained in:
parent
03e2ecf6b8
commit
045fa1e114
3
Makefile
3
Makefile
@ -260,7 +260,8 @@ LIBS-y += drivers/net/npe/libnpe.o
|
||||
endif
|
||||
LIBS-$(CONFIG_OF_EMBED) += dts/libdts.o
|
||||
LIBS-y += arch/$(ARCH)/lib/lib$(ARCH).o
|
||||
LIBS-y += fs/cbfs/libcbfs.o \
|
||||
LIBS-y += fs/libfs.o \
|
||||
fs/cbfs/libcbfs.o \
|
||||
fs/cramfs/libcramfs.o \
|
||||
fs/ext4/libext4fs.o \
|
||||
fs/fat/libfat.o \
|
||||
|
@ -90,11 +90,6 @@ COBJS-$(CONFIG_CMD_ELF) += cmd_elf.o
|
||||
COBJS-$(CONFIG_SYS_HUSH_PARSER) += cmd_exit.o
|
||||
COBJS-$(CONFIG_CMD_EXT4) += cmd_ext4.o
|
||||
COBJS-$(CONFIG_CMD_EXT2) += cmd_ext2.o
|
||||
ifdef CONFIG_CMD_EXT4
|
||||
COBJS-y += cmd_ext_common.o
|
||||
else
|
||||
COBJS-$(CONFIG_CMD_EXT2) += cmd_ext_common.o
|
||||
endif
|
||||
COBJS-$(CONFIG_CMD_FAT) += cmd_fat.o
|
||||
COBJS-$(CONFIG_CMD_FDC)$(CONFIG_CMD_FDOS) += cmd_fdc.o
|
||||
COBJS-$(CONFIG_OF_LIBFDT) += cmd_fdt.o fdt_support.o
|
||||
@ -104,6 +99,7 @@ COBJS-$(CONFIG_CMD_FLASH) += cmd_flash.o
|
||||
ifdef CONFIG_FPGA
|
||||
COBJS-$(CONFIG_CMD_FPGA) += cmd_fpga.o
|
||||
endif
|
||||
COBJS-$(CONFIG_CMD_FS_GENERIC) += cmd_fs.o
|
||||
COBJS-$(CONFIG_CMD_GPIO) += cmd_gpio.o
|
||||
COBJS-$(CONFIG_CMD_I2C) += cmd_i2c.o
|
||||
COBJS-$(CONFIG_CMD_IDE) += cmd_ide.o
|
||||
|
@ -37,15 +37,11 @@
|
||||
/*
|
||||
* Ext2fs support
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <ext_common.h>
|
||||
#include <fs.h>
|
||||
|
||||
int do_ext2ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
if (do_ext_ls(cmdtp, flag, argc, argv))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
return do_ls(cmdtp, flag, argc, argv, FS_TYPE_EXT);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@ -53,10 +49,7 @@ int do_ext2ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
*/
|
||||
int do_ext2load (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
if (do_ext_load(cmdtp, flag, argc, argv))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
return do_fsload(cmdtp, flag, argc, argv, FS_TYPE_EXT);
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
|
@ -47,10 +47,10 @@
|
||||
#include <image.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <ext_common.h>
|
||||
#include <ext4fs.h>
|
||||
#include <linux/stat.h>
|
||||
#include <malloc.h>
|
||||
#include <fs.h>
|
||||
|
||||
#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
|
||||
#include <usb.h>
|
||||
@ -59,18 +59,12 @@
|
||||
int do_ext4_load(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
if (do_ext_load(cmdtp, flag, argc, argv))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
return do_fsload(cmdtp, flag, argc, argv, FS_TYPE_EXT);
|
||||
}
|
||||
|
||||
int do_ext4_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
||||
{
|
||||
if (do_ext_ls(cmdtp, flag, argc, argv))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
return do_ls(cmdtp, flag, argc, argv, FS_TYPE_EXT);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_CMD_EXT4_WRITE)
|
||||
|
@ -1,197 +0,0 @@
|
||||
/*
|
||||
* (C) Copyright 2011 - 2012 Samsung Electronics
|
||||
* EXT2/4 filesystem implementation in Uboot by
|
||||
* Uma Shankar <uma.shankar@samsung.com>
|
||||
* Manjunatha C Achar <a.manjunatha@samsung.com>
|
||||
*
|
||||
* Ext4fs support
|
||||
* made from existing cmd_ext2.c file of Uboot
|
||||
*
|
||||
* (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>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Changelog:
|
||||
* 0.1 - Newly created file for ext4fs support. Taken from cmd_ext2.c
|
||||
* file in uboot. Added ext4fs ls load and write support.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <part.h>
|
||||
#include <config.h>
|
||||
#include <command.h>
|
||||
#include <image.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <ext_common.h>
|
||||
#include <ext4fs.h>
|
||||
#include <linux/stat.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
|
||||
#include <usb.h>
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_DOS_PARTITION) && !defined(CONFIG_EFI_PARTITION)
|
||||
#error DOS or EFI partition support must be selected
|
||||
#endif
|
||||
|
||||
#define DOS_PART_MAGIC_OFFSET 0x1fe
|
||||
#define DOS_FS_TYPE_OFFSET 0x36
|
||||
#define DOS_FS32_TYPE_OFFSET 0x52
|
||||
|
||||
int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
char *filename = NULL;
|
||||
int dev, part;
|
||||
ulong addr = 0;
|
||||
int filelen;
|
||||
disk_partition_t info;
|
||||
block_dev_desc_t *dev_desc;
|
||||
char buf[12];
|
||||
unsigned long count;
|
||||
const char *addr_str;
|
||||
|
||||
count = 0;
|
||||
addr = simple_strtoul(argv[3], NULL, 16);
|
||||
filename = getenv("bootfile");
|
||||
switch (argc) {
|
||||
case 3:
|
||||
addr_str = getenv("loadaddr");
|
||||
if (addr_str != NULL)
|
||||
addr = simple_strtoul(addr_str, NULL, 16);
|
||||
else
|
||||
addr = CONFIG_SYS_LOAD_ADDR;
|
||||
|
||||
break;
|
||||
case 4:
|
||||
break;
|
||||
case 5:
|
||||
filename = argv[4];
|
||||
break;
|
||||
case 6:
|
||||
filename = argv[4];
|
||||
count = simple_strtoul(argv[5], NULL, 16);
|
||||
break;
|
||||
|
||||
default:
|
||||
return cmd_usage(cmdtp);
|
||||
}
|
||||
|
||||
if (!filename) {
|
||||
puts("** No boot file defined **\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1);
|
||||
if (part < 0)
|
||||
return 1;
|
||||
|
||||
dev = dev_desc->dev;
|
||||
printf("Loading file \"%s\" from %s device %d%c%c\n",
|
||||
filename, argv[1], dev,
|
||||
part ? ':' : ' ', part ? part + '0' : ' ');
|
||||
|
||||
ext4fs_set_blk_dev(dev_desc, &info);
|
||||
|
||||
if (!ext4fs_mount(info.size)) {
|
||||
printf("** Bad ext2 partition or disk - %s %d:%d **\n",
|
||||
argv[1], dev, part);
|
||||
ext4fs_close();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
filelen = ext4fs_open(filename);
|
||||
if (filelen < 0) {
|
||||
printf("** File not found %s\n", filename);
|
||||
ext4fs_close();
|
||||
goto fail;
|
||||
}
|
||||
if ((count < filelen) && (count != 0))
|
||||
filelen = count;
|
||||
|
||||
if (ext4fs_read((char *)addr, filelen) != filelen) {
|
||||
printf("** Unable to read \"%s\" from %s %d:%d **\n",
|
||||
filename, argv[1], dev, part);
|
||||
ext4fs_close();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ext4fs_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;
|
||||
fail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
int do_ext_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
||||
{
|
||||
const char *filename = "/";
|
||||
int dev;
|
||||
int part;
|
||||
block_dev_desc_t *dev_desc;
|
||||
disk_partition_t info;
|
||||
|
||||
if (argc < 2)
|
||||
return cmd_usage(cmdtp);
|
||||
|
||||
part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1);
|
||||
if (part < 0)
|
||||
return 1;
|
||||
|
||||
if (argc == 4)
|
||||
filename = argv[3];
|
||||
|
||||
dev = dev_desc->dev;
|
||||
ext4fs_set_blk_dev(dev_desc, &info);
|
||||
|
||||
if (!ext4fs_mount(info.size)) {
|
||||
printf("** Bad ext2 partition or disk - %s %d:%d **\n",
|
||||
argv[1], dev, part);
|
||||
ext4fs_close();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (ext4fs_ls(filename)) {
|
||||
printf("** Error extfs_ls() **\n");
|
||||
ext4fs_close();
|
||||
goto fail;
|
||||
};
|
||||
|
||||
ext4fs_close();
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
return 1;
|
||||
}
|
@ -31,54 +31,11 @@
|
||||
#include <ata.h>
|
||||
#include <part.h>
|
||||
#include <fat.h>
|
||||
|
||||
#include <fs.h>
|
||||
|
||||
int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
long size;
|
||||
unsigned long offset;
|
||||
unsigned long count = 0;
|
||||
unsigned long pos = 0;
|
||||
char buf [12];
|
||||
block_dev_desc_t *dev_desc=NULL;
|
||||
disk_partition_t info;
|
||||
int part, dev;
|
||||
|
||||
if (argc < 5) {
|
||||
printf("usage: fatload <interface> [<dev[:part]>] "
|
||||
"<addr> <filename> [bytes [pos]]\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1);
|
||||
if (part < 0)
|
||||
return 1;
|
||||
|
||||
dev = dev_desc->dev;
|
||||
if (fat_set_blk_dev(dev_desc, &info) != 0) {
|
||||
printf("\n** Unable to use %s %d:%d for fatload **\n",
|
||||
argv[1], dev, part);
|
||||
return 1;
|
||||
}
|
||||
offset = simple_strtoul(argv[3], NULL, 16);
|
||||
if (argc >= 6)
|
||||
count = simple_strtoul(argv[5], NULL, 16);
|
||||
if (argc >= 7)
|
||||
pos = simple_strtoul(argv[6], NULL, 16);
|
||||
size = file_fat_read_at(argv[4], pos, (unsigned char *)offset, count);
|
||||
|
||||
if(size==-1) {
|
||||
printf("\n** Unable to read \"%s\" from %s %d:%d **\n",
|
||||
argv[4], argv[1], dev, part);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("\n%ld bytes read\n", size);
|
||||
|
||||
sprintf(buf, "%lX", size);
|
||||
setenv("filesize", buf);
|
||||
|
||||
return 0;
|
||||
return do_fsload(cmdtp, flag, argc, argv, FS_TYPE_FAT);
|
||||
}
|
||||
|
||||
|
||||
@ -96,34 +53,7 @@ U_BOOT_CMD(
|
||||
|
||||
int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
char *filename = "/";
|
||||
int ret, dev, part;
|
||||
block_dev_desc_t *dev_desc=NULL;
|
||||
disk_partition_t info;
|
||||
|
||||
if (argc < 2) {
|
||||
printf("usage: fatls <interface> [<dev[:part]>] [directory]\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1);
|
||||
if (part < 0)
|
||||
return 1;
|
||||
|
||||
dev = dev_desc->dev;
|
||||
if (fat_set_blk_dev(dev_desc, &info) != 0) {
|
||||
printf("\n** Unable to use %s %d:%d for fatls **\n",
|
||||
argv[1], dev, part);
|
||||
return 1;
|
||||
}
|
||||
if (argc == 4)
|
||||
ret = file_fat_ls(argv[3]);
|
||||
else
|
||||
ret = file_fat_ls(filename);
|
||||
|
||||
if(ret!=0)
|
||||
printf("No Fat FS detected\n");
|
||||
return ret;
|
||||
return do_ls(cmdtp, flag, argc, argv, FS_TYPE_FAT);
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
|
51
common/cmd_fs.c
Normal file
51
common/cmd_fs.c
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Inspired by cmd_ext_common.c, cmd_fat.c.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <fs.h>
|
||||
|
||||
int do_fsload_wrapper(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
return do_fsload(cmdtp, flag, argc, argv, FS_TYPE_ANY);
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
fsload, 7, 0, do_fsload_wrapper,
|
||||
"load binary file from a filesystem",
|
||||
"<interface> [<dev[:part]> [<addr> [<filename> [bytes [pos]]]]]\n"
|
||||
" - Load binary file 'filename' from partition 'part' on device\n"
|
||||
" type 'interface' instance 'dev' to address 'addr' in memory.\n"
|
||||
" 'bytes' gives the size to load in bytes.\n"
|
||||
" If 'bytes' is 0 or omitted, the file is read until the end.\n"
|
||||
" 'pos' gives the file byte position to start reading from.\n"
|
||||
" If 'pos' is 0 or omitted, the file is read from the start."
|
||||
);
|
||||
|
||||
int do_ls_wrapper(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
return do_ls(cmdtp, flag, argc, argv, FS_TYPE_ANY);
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
ls, 4, 1, do_ls_wrapper,
|
||||
"list files in a directory (default /)",
|
||||
"<interface> [<dev[:part]> [directory]]\n"
|
||||
" - List files in directory 'directory' of partition 'part' on\n"
|
||||
" device type 'interface' instance 'dev'."
|
||||
);
|
47
fs/Makefile
Normal file
47
fs/Makefile
Normal file
@ -0,0 +1,47 @@
|
||||
#
|
||||
# (C) Copyright 2000-2006
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
# Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
|
||||
#
|
||||
# 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
|
||||
#
|
||||
|
||||
include $(TOPDIR)/config.mk
|
||||
|
||||
LIB = $(obj)libfs.o
|
||||
|
||||
COBJS-y += fs.o
|
||||
|
||||
COBJS := $(COBJS-y)
|
||||
SRCS := $(COBJS:.o=.c)
|
||||
OBJS := $(addprefix $(obj),$(COBJS))
|
||||
|
||||
all: $(LIB)
|
||||
|
||||
$(LIB): $(obj).depend $(OBJS)
|
||||
$(call cmd_link_o_target, $(OBJS))
|
||||
|
||||
#########################################################################
|
||||
|
||||
# defines $(obj).depend target
|
||||
include $(SRCTREE)/rules.mk
|
||||
|
||||
sinclude $(obj).depend
|
||||
|
||||
#########################################################################
|
308
fs/fs.c
Normal file
308
fs/fs.c
Normal file
@ -0,0 +1,308 @@
|
||||
/*
|
||||
* Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <part.h>
|
||||
#include <ext4fs.h>
|
||||
#include <fat.h>
|
||||
#include <fs.h>
|
||||
|
||||
static block_dev_desc_t *fs_dev_desc;
|
||||
static disk_partition_t fs_partition;
|
||||
static int fs_type = FS_TYPE_ANY;
|
||||
|
||||
static inline int fs_ls_unsupported(const char *dirname)
|
||||
{
|
||||
printf("** Unrecognized filesystem type **\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int fs_read_unsupported(const char *filename, ulong addr,
|
||||
int offset, int len)
|
||||
{
|
||||
printf("** Unrecognized filesystem type **\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FS_FAT
|
||||
static int fs_probe_fat(void)
|
||||
{
|
||||
return fat_set_blk_dev(fs_dev_desc, &fs_partition);
|
||||
}
|
||||
|
||||
static void fs_close_fat(void)
|
||||
{
|
||||
}
|
||||
|
||||
#define fs_ls_fat file_fat_ls
|
||||
|
||||
static int fs_read_fat(const char *filename, ulong addr, int offset, int len)
|
||||
{
|
||||
int len_read;
|
||||
|
||||
len_read = file_fat_read_at(filename, offset,
|
||||
(unsigned char *)addr, len);
|
||||
if (len_read == -1) {
|
||||
printf("** Unable to read file %s **\n", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return len_read;
|
||||
}
|
||||
#else
|
||||
static inline int fs_probe_fat(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline void fs_close_fat(void)
|
||||
{
|
||||
}
|
||||
|
||||
#define fs_ls_fat fs_ls_unsupported
|
||||
#define fs_read_fat fs_read_unsupported
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FS_EXT4
|
||||
static int fs_probe_ext(void)
|
||||
{
|
||||
ext4fs_set_blk_dev(fs_dev_desc, &fs_partition);
|
||||
|
||||
if (!ext4fs_mount(fs_partition.size)) {
|
||||
ext4fs_close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fs_close_ext(void)
|
||||
{
|
||||
ext4fs_close();
|
||||
}
|
||||
|
||||
#define fs_ls_ext ext4fs_ls
|
||||
|
||||
static int fs_read_ext(const char *filename, ulong addr, int offset, int len)
|
||||
{
|
||||
int file_len;
|
||||
int len_read;
|
||||
|
||||
if (offset != 0) {
|
||||
printf("** Cannot support non-zero offset **\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
file_len = ext4fs_open(filename);
|
||||
if (file_len < 0) {
|
||||
printf("** File not found %s **\n", filename);
|
||||
ext4fs_close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len == 0)
|
||||
len = file_len;
|
||||
|
||||
len_read = ext4fs_read((char *)addr, len);
|
||||
ext4fs_close();
|
||||
|
||||
if (len_read != len) {
|
||||
printf("** Unable to read file %s **\n", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return len_read;
|
||||
}
|
||||
#else
|
||||
static inline int fs_probe_ext(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline void fs_close_ext(void)
|
||||
{
|
||||
}
|
||||
|
||||
#define fs_ls_ext fs_ls_unsupported
|
||||
#define fs_read_ext fs_read_unsupported
|
||||
#endif
|
||||
|
||||
static const struct {
|
||||
int fstype;
|
||||
int (*probe)(void);
|
||||
} fstypes[] = {
|
||||
{
|
||||
.fstype = FS_TYPE_FAT,
|
||||
.probe = fs_probe_fat,
|
||||
},
|
||||
{
|
||||
.fstype = FS_TYPE_EXT,
|
||||
.probe = fs_probe_ext,
|
||||
},
|
||||
};
|
||||
|
||||
int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype)
|
||||
{
|
||||
int part, i;
|
||||
|
||||
part = get_device_and_partition(ifname, dev_part_str, &fs_dev_desc,
|
||||
&fs_partition, 1);
|
||||
if (part < 0)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(fstypes); i++) {
|
||||
if ((fstype != FS_TYPE_ANY) && (fstype != fstypes[i].fstype))
|
||||
continue;
|
||||
|
||||
if (!fstypes[i].probe()) {
|
||||
fs_type = fstypes[i].fstype;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
printf("** Unrecognized filesystem type **\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void fs_close(void)
|
||||
{
|
||||
switch (fs_type) {
|
||||
case FS_TYPE_FAT:
|
||||
fs_close_fat();
|
||||
break;
|
||||
case FS_TYPE_EXT:
|
||||
fs_close_ext();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
fs_type = FS_TYPE_ANY;
|
||||
}
|
||||
|
||||
int fs_ls(const char *dirname)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (fs_type) {
|
||||
case FS_TYPE_FAT:
|
||||
ret = fs_ls_fat(dirname);
|
||||
break;
|
||||
case FS_TYPE_EXT:
|
||||
ret = fs_ls_ext(dirname);
|
||||
break;
|
||||
default:
|
||||
ret = fs_ls_unsupported(dirname);
|
||||
break;
|
||||
}
|
||||
|
||||
fs_close();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fs_read(const char *filename, ulong addr, int offset, int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (fs_type) {
|
||||
case FS_TYPE_FAT:
|
||||
ret = fs_read_fat(filename, addr, offset, len);
|
||||
break;
|
||||
case FS_TYPE_EXT:
|
||||
ret = fs_read_ext(filename, addr, offset, len);
|
||||
break;
|
||||
default:
|
||||
ret = fs_read_unsupported(filename, addr, offset, len);
|
||||
break;
|
||||
}
|
||||
|
||||
fs_close();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int do_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
|
||||
int fstype)
|
||||
{
|
||||
unsigned long addr;
|
||||
const char *addr_str;
|
||||
const char *filename;
|
||||
unsigned long bytes;
|
||||
unsigned long pos;
|
||||
int len_read;
|
||||
char buf[12];
|
||||
|
||||
if (argc < 5)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
if (fs_set_blk_dev(argv[1], argv[2], fstype))
|
||||
return 1;
|
||||
|
||||
if (argc >= 4) {
|
||||
addr = simple_strtoul(argv[3], NULL, 0);
|
||||
} else {
|
||||
addr_str = getenv("loadaddr");
|
||||
if (addr_str != NULL)
|
||||
addr = simple_strtoul(addr_str, NULL, 16);
|
||||
else
|
||||
addr = CONFIG_SYS_LOAD_ADDR;
|
||||
}
|
||||
if (argc >= 5) {
|
||||
filename = argv[4];
|
||||
} else {
|
||||
filename = getenv("bootfile");
|
||||
if (!filename) {
|
||||
puts("** No boot file defined **\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (argc >= 6)
|
||||
bytes = simple_strtoul(argv[5], NULL, 0);
|
||||
else
|
||||
bytes = 0;
|
||||
if (argc >= 7)
|
||||
pos = simple_strtoul(argv[6], NULL, 0);
|
||||
else
|
||||
pos = 0;
|
||||
|
||||
len_read = fs_read(filename, addr, pos, bytes);
|
||||
if (len_read <= 0)
|
||||
return 1;
|
||||
|
||||
printf("%d bytes read\n", len_read);
|
||||
|
||||
sprintf(buf, "0x%x", len_read);
|
||||
setenv("filesize", buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
|
||||
int fstype)
|
||||
{
|
||||
if (argc < 2)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
if (fs_set_blk_dev(argv[1], (argc >= 3) ? argv[2] : NULL, fstype))
|
||||
return 1;
|
||||
|
||||
if (fs_ls(argc == 4 ? argv[3] : "/"))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
@ -195,7 +195,4 @@ int do_ext4_load(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
int do_ext4_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
|
||||
int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
char *const argv[]);
|
||||
int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
char *const argv[]);
|
||||
int do_ext_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
|
||||
#endif
|
||||
|
65
include/fs.h
Normal file
65
include/fs.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _FS_H
|
||||
#define _FS_H
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#define FS_TYPE_ANY 0
|
||||
#define FS_TYPE_FAT 1
|
||||
#define FS_TYPE_EXT 2
|
||||
|
||||
/*
|
||||
* Tell the fs layer which block device an partition to use for future
|
||||
* commands. This also internally identifies the filesystem that is present
|
||||
* within the partition. The identification process may be limited to a
|
||||
* specific filesystem type by passing FS_* in the fstype parameter.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
* Returns non-zero if there is an error accessing the disk or partition, or
|
||||
* no known filesystem type could be recognized on it.
|
||||
*/
|
||||
int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype);
|
||||
|
||||
/*
|
||||
* Print the list of files on the partition previously set by fs_set_blk_dev(),
|
||||
* in directory "dirname".
|
||||
*
|
||||
* Returns 0 on success. Returns non-zero on error.
|
||||
*/
|
||||
int fs_ls(const char *dirname);
|
||||
|
||||
/*
|
||||
* Read file "filename" from the partition previously set by fs_set_blk_dev(),
|
||||
* to address "addr", starting at byte offset "offset", and reading "len"
|
||||
* bytes. "offset" may be 0 to read from the start of the file. "len" may be
|
||||
* 0 to read the entire file. Note that not all filesystem types support
|
||||
* either/both offset!=0 or len!=0.
|
||||
*
|
||||
* Returns number of bytes read on success. Returns <= 0 on error.
|
||||
*/
|
||||
int fs_read(const char *filename, ulong addr, int offset, int len);
|
||||
|
||||
/*
|
||||
* Common implementation for various filesystem commands, optionally limited
|
||||
* to a specific filesystem type via the fstype parameter.
|
||||
*/
|
||||
int do_fsload(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
|
||||
int fstype);
|
||||
int do_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
|
||||
int fstype);
|
||||
|
||||
#endif /* _FS_H */
|
Loading…
Reference in New Issue
Block a user