mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-03-16 06:46:59 +00: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
11 changed files with 483 additions and 298 deletions
3
Makefile
3
Makefile
|
@ -260,7 +260,8 @@ LIBS-y += drivers/net/npe/libnpe.o
|
||||||
endif
|
endif
|
||||||
LIBS-$(CONFIG_OF_EMBED) += dts/libdts.o
|
LIBS-$(CONFIG_OF_EMBED) += dts/libdts.o
|
||||||
LIBS-y += arch/$(ARCH)/lib/lib$(ARCH).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/cramfs/libcramfs.o \
|
||||||
fs/ext4/libext4fs.o \
|
fs/ext4/libext4fs.o \
|
||||||
fs/fat/libfat.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_SYS_HUSH_PARSER) += cmd_exit.o
|
||||||
COBJS-$(CONFIG_CMD_EXT4) += cmd_ext4.o
|
COBJS-$(CONFIG_CMD_EXT4) += cmd_ext4.o
|
||||||
COBJS-$(CONFIG_CMD_EXT2) += cmd_ext2.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_FAT) += cmd_fat.o
|
||||||
COBJS-$(CONFIG_CMD_FDC)$(CONFIG_CMD_FDOS) += cmd_fdc.o
|
COBJS-$(CONFIG_CMD_FDC)$(CONFIG_CMD_FDOS) += cmd_fdc.o
|
||||||
COBJS-$(CONFIG_OF_LIBFDT) += cmd_fdt.o fdt_support.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
|
ifdef CONFIG_FPGA
|
||||||
COBJS-$(CONFIG_CMD_FPGA) += cmd_fpga.o
|
COBJS-$(CONFIG_CMD_FPGA) += cmd_fpga.o
|
||||||
endif
|
endif
|
||||||
|
COBJS-$(CONFIG_CMD_FS_GENERIC) += cmd_fs.o
|
||||||
COBJS-$(CONFIG_CMD_GPIO) += cmd_gpio.o
|
COBJS-$(CONFIG_CMD_GPIO) += cmd_gpio.o
|
||||||
COBJS-$(CONFIG_CMD_I2C) += cmd_i2c.o
|
COBJS-$(CONFIG_CMD_I2C) += cmd_i2c.o
|
||||||
COBJS-$(CONFIG_CMD_IDE) += cmd_ide.o
|
COBJS-$(CONFIG_CMD_IDE) += cmd_ide.o
|
||||||
|
|
|
@ -37,15 +37,11 @@
|
||||||
/*
|
/*
|
||||||
* Ext2fs support
|
* Ext2fs support
|
||||||
*/
|
*/
|
||||||
#include <common.h>
|
#include <fs.h>
|
||||||
#include <ext_common.h>
|
|
||||||
|
|
||||||
int do_ext2ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
int do_ext2ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
{
|
{
|
||||||
if (do_ext_ls(cmdtp, flag, argc, argv))
|
return do_ls(cmdtp, flag, argc, argv, FS_TYPE_EXT);
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
@ -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[])
|
int do_ext2load (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
{
|
{
|
||||||
if (do_ext_load(cmdtp, flag, argc, argv))
|
return do_fsload(cmdtp, flag, argc, argv, FS_TYPE_EXT);
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
U_BOOT_CMD(
|
U_BOOT_CMD(
|
||||||
|
|
|
@ -47,10 +47,10 @@
|
||||||
#include <image.h>
|
#include <image.h>
|
||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
#include <ext_common.h>
|
|
||||||
#include <ext4fs.h>
|
#include <ext4fs.h>
|
||||||
#include <linux/stat.h>
|
#include <linux/stat.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
#include <fs.h>
|
||||||
|
|
||||||
#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
|
#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
|
||||||
#include <usb.h>
|
#include <usb.h>
|
||||||
|
@ -59,18 +59,12 @@
|
||||||
int do_ext4_load(cmd_tbl_t *cmdtp, int flag, int argc,
|
int do_ext4_load(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||||
char *const argv[])
|
char *const argv[])
|
||||||
{
|
{
|
||||||
if (do_ext_load(cmdtp, flag, argc, argv))
|
return do_fsload(cmdtp, flag, argc, argv, FS_TYPE_EXT);
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_ext4_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
int do_ext4_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
||||||
{
|
{
|
||||||
if (do_ext_ls(cmdtp, flag, argc, argv))
|
return do_ls(cmdtp, flag, argc, argv, FS_TYPE_EXT);
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_CMD_EXT4_WRITE)
|
#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 <ata.h>
|
||||||
#include <part.h>
|
#include <part.h>
|
||||||
#include <fat.h>
|
#include <fat.h>
|
||||||
|
#include <fs.h>
|
||||||
|
|
||||||
int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
{
|
{
|
||||||
long size;
|
return do_fsload(cmdtp, flag, argc, argv, FS_TYPE_FAT);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -96,34 +53,7 @@ U_BOOT_CMD(
|
||||||
|
|
||||||
int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
{
|
{
|
||||||
char *filename = "/";
|
return do_ls(cmdtp, flag, argc, argv, FS_TYPE_FAT);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
U_BOOT_CMD(
|
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_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
|
||||||
int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc,
|
int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||||
char *const argv[]);
|
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
|
#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…
Add table
Reference in a new issue