cmd_extX: use common get_device_and_partition function
Convert ext2/4 load, ls, and write functions to use common device and partition parsing function. With the common function "dev:part" can come from the environment and a '-' can be used in that case. Signed-off-by: Rob Herring <rob.herring@calxeda.com>
This commit is contained in:
parent
9450106296
commit
81180819b8
@ -56,21 +56,6 @@
|
|||||||
#include <usb.h>
|
#include <usb.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(CONFIG_DOS_PARTITION) && !defined(CONFIG_EFI_PARTITION)
|
|
||||||
#error DOS or EFI partition support must be selected
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint64_t total_sector;
|
|
||||||
uint64_t part_offset;
|
|
||||||
#if defined(CONFIG_CMD_EXT4_WRITE)
|
|
||||||
static uint64_t part_size;
|
|
||||||
static uint16_t cur_part = 1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define DOS_PART_MAGIC_OFFSET 0x1fe
|
|
||||||
#define DOS_FS_TYPE_OFFSET 0x36
|
|
||||||
#define DOS_FS32_TYPE_OFFSET 0x52
|
|
||||||
|
|
||||||
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[])
|
||||||
{
|
{
|
||||||
@ -89,77 +74,24 @@ int do_ext4_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_CMD_EXT4_WRITE)
|
#if defined(CONFIG_CMD_EXT4_WRITE)
|
||||||
static int ext4_register_device(block_dev_desc_t *dev_desc, int part_no)
|
|
||||||
{
|
|
||||||
unsigned char buffer[SECTOR_SIZE];
|
|
||||||
disk_partition_t info;
|
|
||||||
|
|
||||||
if (!dev_desc->block_read)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* check if we have a MBR (on floppies we have only a PBR) */
|
|
||||||
if (dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1) {
|
|
||||||
printf("** Can't read from device %d **\n", dev_desc->dev);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 ||
|
|
||||||
buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) {
|
|
||||||
/* no signature found */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* First we assume there is a MBR */
|
|
||||||
if (!get_partition_info(dev_desc, part_no, &info)) {
|
|
||||||
part_offset = info.start;
|
|
||||||
cur_part = part_no;
|
|
||||||
part_size = info.size;
|
|
||||||
} else if ((strncmp((char *)&buffer[DOS_FS_TYPE_OFFSET],
|
|
||||||
"FAT", 3) == 0) || (strncmp((char *)&buffer
|
|
||||||
[DOS_FS32_TYPE_OFFSET],
|
|
||||||
"FAT32", 5) == 0)) {
|
|
||||||
/* ok, we assume we are on a PBR only */
|
|
||||||
cur_part = 1;
|
|
||||||
part_offset = 0;
|
|
||||||
} else {
|
|
||||||
printf("** Partition %d not valid on device %d **\n",
|
|
||||||
part_no, dev_desc->dev);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
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[])
|
||||||
{
|
{
|
||||||
const char *filename = "/";
|
const char *filename = "/";
|
||||||
int part_length;
|
int dev, part;
|
||||||
unsigned long part = 1;
|
|
||||||
int dev;
|
|
||||||
char *ep;
|
|
||||||
unsigned long ram_address;
|
unsigned long ram_address;
|
||||||
unsigned long file_size;
|
unsigned long file_size;
|
||||||
disk_partition_t info;
|
disk_partition_t info;
|
||||||
struct ext_filesystem *fs;
|
block_dev_desc_t *dev_desc;
|
||||||
|
|
||||||
if (argc < 6)
|
if (argc < 6)
|
||||||
return cmd_usage(cmdtp);
|
return cmd_usage(cmdtp);
|
||||||
|
|
||||||
dev = (int)simple_strtoul(argv[2], &ep, 16);
|
part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info);
|
||||||
ext4_dev_desc = get_dev(argv[1], dev);
|
if (part < 0)
|
||||||
if (ext4_dev_desc == NULL) {
|
|
||||||
printf("Block device %s %d not supported\n", argv[1], dev);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
|
|
||||||
fs = get_fs();
|
dev = dev_desc->dev;
|
||||||
if (*ep) {
|
|
||||||
if (*ep != ':') {
|
|
||||||
puts("Invalid boot device, use `dev[:part]'\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
part = simple_strtoul(++ep, NULL, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get the filename */
|
/* get the filename */
|
||||||
filename = argv[3];
|
filename = argv[3];
|
||||||
@ -171,30 +103,10 @@ int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc,
|
|||||||
file_size = simple_strtoul(argv[5], NULL, 10);
|
file_size = simple_strtoul(argv[5], NULL, 10);
|
||||||
|
|
||||||
/* set the device as block device */
|
/* set the device as block device */
|
||||||
part_length = ext4fs_set_blk_dev(ext4_dev_desc, part);
|
ext4fs_set_blk_dev(dev_desc, &info);
|
||||||
if (part_length == 0) {
|
|
||||||
printf("Bad partition - %s %d:%lu\n", argv[1], dev, part);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* register the device and partition */
|
|
||||||
if (ext4_register_device(ext4_dev_desc, part) != 0) {
|
|
||||||
printf("Unable to use %s %d:%lu for fattable\n",
|
|
||||||
argv[1], dev, part);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get the partition information */
|
|
||||||
if (!get_partition_info(ext4_dev_desc, part, &info)) {
|
|
||||||
total_sector = (info.size * info.blksz) / SECTOR_SIZE;
|
|
||||||
fs->total_sect = total_sector;
|
|
||||||
} else {
|
|
||||||
printf("error : get partition info\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* mount the filesystem */
|
/* mount the filesystem */
|
||||||
if (!ext4fs_mount(part_length)) {
|
if (!ext4fs_mount(info.size)) {
|
||||||
printf("Bad ext4 partition %s %d:%lu\n", argv[1], dev, part);
|
printf("Bad ext4 partition %s %d:%lu\n", argv[1], dev, part);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -68,13 +68,11 @@ int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc,
|
|||||||
char *const argv[])
|
char *const argv[])
|
||||||
{
|
{
|
||||||
char *filename = NULL;
|
char *filename = NULL;
|
||||||
char *ep;
|
int dev, part;
|
||||||
int dev;
|
|
||||||
unsigned long part = 1;
|
|
||||||
ulong addr = 0;
|
ulong addr = 0;
|
||||||
ulong part_length;
|
|
||||||
int filelen;
|
int filelen;
|
||||||
disk_partition_t info;
|
disk_partition_t info;
|
||||||
|
block_dev_desc_t *dev_desc;
|
||||||
char buf[12];
|
char buf[12];
|
||||||
unsigned long count;
|
unsigned long count;
|
||||||
const char *addr_str;
|
const char *addr_str;
|
||||||
@ -110,50 +108,19 @@ int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev = (int)simple_strtoul(argv[2], &ep, 16);
|
part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info);
|
||||||
ext4_dev_desc = get_dev(argv[1], dev);
|
if (part < 0)
|
||||||
if (ext4_dev_desc == NULL) {
|
|
||||||
printf("** Block device %s %d not supported\n", argv[1], dev);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
|
|
||||||
if (*ep) {
|
dev = dev_desc->dev;
|
||||||
if (*ep != ':') {
|
printf("Loading file \"%s\" from %s device %d%c%c\n",
|
||||||
puts("** Invalid boot device, use `dev[:part]' **\n");
|
filename, argv[1], dev,
|
||||||
goto fail;
|
part ? ':' : ' ', part ? part + '0' : ' ');
|
||||||
}
|
|
||||||
part = simple_strtoul(++ep, NULL, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (part != 0) {
|
ext4fs_set_blk_dev(dev_desc, &info);
|
||||||
if (get_partition_info(ext4_dev_desc, part, &info)) {
|
|
||||||
printf("** Bad partition %lu **\n", part);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strncmp((char *)info.type, BOOT_PART_TYPE,
|
if (!ext4fs_mount(info.size)) {
|
||||||
strlen(BOOT_PART_TYPE)) != 0) {
|
printf("** Bad ext2 partition or disk - %s %d:%d **\n",
|
||||||
printf("** Invalid partition type \"%s\""
|
|
||||||
" (expect \"" BOOT_PART_TYPE "\")\n", info.type);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
printf("Loading file \"%s\" "
|
|
||||||
"from %s device %d:%lu %s\n",
|
|
||||||
filename, argv[1], dev, part, info.name);
|
|
||||||
} else {
|
|
||||||
printf("Loading file \"%s\" from %s device %d\n",
|
|
||||||
filename, argv[1], dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
part_length = ext4fs_set_blk_dev(ext4_dev_desc, part);
|
|
||||||
if (part_length == 0) {
|
|
||||||
printf("**Bad partition - %s %d:%lu **\n", argv[1], dev, part);
|
|
||||||
ext4fs_close();
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ext4fs_mount(part_length)) {
|
|
||||||
printf("** Bad ext2 partition or disk - %s %d:%lu **\n",
|
|
||||||
argv[1], dev, part);
|
argv[1], dev, part);
|
||||||
ext4fs_close();
|
ext4fs_close();
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -169,7 +136,7 @@ int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc,
|
|||||||
filelen = count;
|
filelen = count;
|
||||||
|
|
||||||
if (ext4fs_read((char *)addr, filelen) != filelen) {
|
if (ext4fs_read((char *)addr, filelen) != filelen) {
|
||||||
printf("** Unable to read \"%s\" from %s %d:%lu **\n",
|
printf("** Unable to read \"%s\" from %s %d:%d **\n",
|
||||||
filename, argv[1], dev, part);
|
filename, argv[1], dev, part);
|
||||||
ext4fs_close();
|
ext4fs_close();
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -192,41 +159,25 @@ int do_ext_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
|||||||
{
|
{
|
||||||
const char *filename = "/";
|
const char *filename = "/";
|
||||||
int dev;
|
int dev;
|
||||||
unsigned long part = 1;
|
int part;
|
||||||
char *ep;
|
block_dev_desc_t *dev_desc;
|
||||||
int part_length;
|
disk_partition_t info;
|
||||||
if (argc < 3)
|
|
||||||
|
if (argc < 2)
|
||||||
return cmd_usage(cmdtp);
|
return cmd_usage(cmdtp);
|
||||||
|
|
||||||
dev = (int)simple_strtoul(argv[2], &ep, 16);
|
part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info);
|
||||||
|
if (part < 0)
|
||||||
ext4_dev_desc = get_dev(argv[1], dev);
|
|
||||||
|
|
||||||
if (ext4_dev_desc == NULL) {
|
|
||||||
printf("\n** Block device %s %d not supported\n", argv[1], dev);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
|
|
||||||
if (*ep) {
|
|
||||||
if (*ep != ':') {
|
|
||||||
puts("\n** Invalid boot device, use `dev[:part]' **\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
part = simple_strtoul(++ep, NULL, 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argc == 4)
|
if (argc == 4)
|
||||||
filename = argv[3];
|
filename = argv[3];
|
||||||
|
|
||||||
part_length = ext4fs_set_blk_dev(ext4_dev_desc, part);
|
dev = dev_desc->dev;
|
||||||
if (part_length == 0) {
|
ext4fs_set_blk_dev(dev_desc, &info);
|
||||||
printf("** Bad partition - %s %d:%lu **\n", argv[1], dev, part);
|
|
||||||
ext4fs_close();
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ext4fs_mount(part_length)) {
|
if (!ext4fs_mount(info.size)) {
|
||||||
printf("** Bad ext2 partition or disk - %s %d:%lu **\n",
|
printf("** Bad ext2 partition or disk - %s %d:%d **\n",
|
||||||
argv[1], dev, part);
|
argv[1], dev, part);
|
||||||
ext4fs_close();
|
ext4fs_close();
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -38,26 +38,20 @@
|
|||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
#include <ext4fs.h>
|
||||||
#include <ext_common.h>
|
#include <ext_common.h>
|
||||||
|
|
||||||
static block_dev_desc_t *ext4fs_block_dev_desc;
|
unsigned long part_offset;
|
||||||
static disk_partition_t part_info;
|
|
||||||
|
|
||||||
int ext4fs_set_blk_dev(block_dev_desc_t *rbdd, int part)
|
static block_dev_desc_t *ext4fs_block_dev_desc;
|
||||||
|
static disk_partition_t *part_info;
|
||||||
|
|
||||||
|
void ext4fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info)
|
||||||
{
|
{
|
||||||
ext4fs_block_dev_desc = rbdd;
|
ext4fs_block_dev_desc = rbdd;
|
||||||
|
part_info = info;
|
||||||
if (part == 0) {
|
part_offset = info->start;
|
||||||
/* disk doesn't use partition table */
|
get_fs()->total_sect = (info->size * info->blksz) / SECTOR_SIZE;
|
||||||
part_info.start = 0;
|
|
||||||
part_info.size = rbdd->lba;
|
|
||||||
part_info.blksz = rbdd->blksz;
|
|
||||||
} else {
|
|
||||||
if (get_partition_info(ext4fs_block_dev_desc,
|
|
||||||
part, &part_info))
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return part_info.size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
|
int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
|
||||||
@ -68,7 +62,7 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
|
|||||||
/* Check partition boundaries */
|
/* Check partition boundaries */
|
||||||
if ((sector < 0)
|
if ((sector < 0)
|
||||||
|| ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) >=
|
|| ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS)) >=
|
||||||
part_info.size)) {
|
part_info->size)) {
|
||||||
printf("%s read outside partition %d\n", __func__, sector);
|
printf("%s read outside partition %d\n", __func__, sector);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -88,7 +82,7 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
|
|||||||
/* read first part which isn't aligned with start of sector */
|
/* read first part which isn't aligned with start of sector */
|
||||||
if (ext4fs_block_dev_desc->
|
if (ext4fs_block_dev_desc->
|
||||||
block_read(ext4fs_block_dev_desc->dev,
|
block_read(ext4fs_block_dev_desc->dev,
|
||||||
part_info.start + sector, 1,
|
part_info->start + sector, 1,
|
||||||
(unsigned long *) sec_buf) != 1) {
|
(unsigned long *) sec_buf) != 1) {
|
||||||
printf(" ** ext2fs_devread() read error **\n");
|
printf(" ** ext2fs_devread() read error **\n");
|
||||||
return 0;
|
return 0;
|
||||||
@ -111,14 +105,14 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
|
|||||||
|
|
||||||
block_len = SECTOR_SIZE;
|
block_len = SECTOR_SIZE;
|
||||||
ext4fs_block_dev_desc->block_read(ext4fs_block_dev_desc->dev,
|
ext4fs_block_dev_desc->block_read(ext4fs_block_dev_desc->dev,
|
||||||
part_info.start + sector,
|
part_info->start + sector,
|
||||||
1, (unsigned long *)p);
|
1, (unsigned long *)p);
|
||||||
memcpy(buf, p, byte_len);
|
memcpy(buf, p, byte_len);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ext4fs_block_dev_desc->block_read(ext4fs_block_dev_desc->dev,
|
if (ext4fs_block_dev_desc->block_read(ext4fs_block_dev_desc->dev,
|
||||||
part_info.start + sector,
|
part_info->start + sector,
|
||||||
block_len / SECTOR_SIZE,
|
block_len / SECTOR_SIZE,
|
||||||
(unsigned long *) buf) !=
|
(unsigned long *) buf) !=
|
||||||
block_len / SECTOR_SIZE) {
|
block_len / SECTOR_SIZE) {
|
||||||
@ -134,7 +128,7 @@ int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf)
|
|||||||
/* read rest of data which are not in whole sector */
|
/* read rest of data which are not in whole sector */
|
||||||
if (ext4fs_block_dev_desc->
|
if (ext4fs_block_dev_desc->
|
||||||
block_read(ext4fs_block_dev_desc->dev,
|
block_read(ext4fs_block_dev_desc->dev,
|
||||||
part_info.start + sector, 1,
|
part_info->start + sector, 1,
|
||||||
(unsigned long *) sec_buf) != 1) {
|
(unsigned long *) sec_buf) != 1) {
|
||||||
printf("* %s read error - last part\n", __func__);
|
printf("* %s read error - last part\n", __func__);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -62,7 +62,6 @@ static inline void *zalloc(size_t size)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern unsigned long part_offset;
|
|
||||||
int ext4fs_read_inode(struct ext2_data *data, int ino,
|
int ext4fs_read_inode(struct ext2_data *data, int ino,
|
||||||
struct ext2_inode *inode);
|
struct ext2_inode *inode);
|
||||||
int ext4fs_read_file(struct ext2fs_node *node, int pos,
|
int ext4fs_read_file(struct ext2fs_node *node, int pos,
|
||||||
|
@ -43,7 +43,6 @@
|
|||||||
#include "ext4_common.h"
|
#include "ext4_common.h"
|
||||||
|
|
||||||
int ext4fs_symlinknest;
|
int ext4fs_symlinknest;
|
||||||
block_dev_desc_t *ext4_dev_desc;
|
|
||||||
struct ext_filesystem ext_fs;
|
struct ext_filesystem ext_fs;
|
||||||
|
|
||||||
struct ext_filesystem *get_fs(void)
|
struct ext_filesystem *get_fs(void)
|
||||||
|
@ -113,7 +113,6 @@ struct ext_filesystem {
|
|||||||
block_dev_desc_t *dev_desc;
|
block_dev_desc_t *dev_desc;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern block_dev_desc_t *ext4_dev_desc;
|
|
||||||
extern struct ext2_data *ext4fs_root;
|
extern struct ext2_data *ext4fs_root;
|
||||||
extern struct ext2fs_node *ext4fs_file;
|
extern struct ext2fs_node *ext4fs_file;
|
||||||
|
|
||||||
@ -137,6 +136,6 @@ void ext4fs_close(void);
|
|||||||
int ext4fs_ls(const char *dirname);
|
int ext4fs_ls(const char *dirname);
|
||||||
void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot);
|
void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot);
|
||||||
int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf);
|
int ext4fs_devread(int sector, int byte_offset, int byte_len, char *buf);
|
||||||
int ext4fs_set_blk_dev(block_dev_desc_t *rbdd, int part);
|
void ext4fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info);
|
||||||
long int read_allocated_block(struct ext2_inode *inode, int fileblock);
|
long int read_allocated_block(struct ext2_inode *inode, int fileblock);
|
||||||
#endif
|
#endif
|
||||||
|
@ -186,6 +186,8 @@ struct ext2_data {
|
|||||||
struct ext2fs_node diropen;
|
struct ext2fs_node diropen;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern unsigned long part_offset;
|
||||||
|
|
||||||
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[]);
|
||||||
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[]);
|
||||||
int do_ext4_load(cmd_tbl_t *cmdtp, int flag, int argc,
|
int do_ext4_load(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||||
|
Loading…
Reference in New Issue
Block a user