diff options
| author | Kenneth Waters <kwaters@chromium.org> | 2012-12-05 14:46:30 +0000 | 
|---|---|---|
| committer | Tom Rini <trini@ti.com> | 2012-12-11 13:17:33 -0700 | 
| commit | ff048ea916f74a40c18b5aaa5f357dce1c75bffa (patch) | |
| tree | 1ca3bf14aa8098a6b937f8cbccbd3f764a47c3c4 /common/cmd_read.c | |
| parent | 53fdc7ef2e43902c4415a81a434c35f9ed8713bc (diff) | |
| download | olio-uboot-2014.01-ff048ea916f74a40c18b5aaa5f357dce1c75bffa.tar.xz olio-uboot-2014.01-ff048ea916f74a40c18b5aaa5f357dce1c75bffa.zip | |
Add a command to read raw blocks from a partition
Sometimes data is on a block device and within a partition, but not in a
particular filesystem.
This commands permits reading raw data from a partition.
Signed-off-by: Kenneth Waters <kwaters@chromium.org>
Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'common/cmd_read.c')
| -rw-r--r-- | common/cmd_read.c | 81 | 
1 files changed, 81 insertions, 0 deletions
| diff --git a/common/cmd_read.c b/common/cmd_read.c new file mode 100644 index 000000000..f0fc9bfe1 --- /dev/null +++ b/common/cmd_read.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + */ + +#include <common.h> +#include <command.h> +#include <part.h> + +int do_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ +	char *ep; +	block_dev_desc_t *dev_desc = NULL; +	int dev; +	int part = 0; +	disk_partition_t part_info; +	ulong offset = 0u; +	ulong limit = 0u; +	void *addr; +	uint blk; +	uint cnt; + +	if (argc != 6) { +		cmd_usage(cmdtp); +		return 1; +	} + +	dev = (int)simple_strtoul(argv[2], &ep, 16); +	if (*ep) { +		if (*ep != ':') { +			printf("Invalid block device %s\n", argv[2]); +			return 1; +		} +		part = (int)simple_strtoul(++ep, NULL, 16); +	} + +	dev_desc = get_dev(argv[1], dev); +	if (dev_desc == NULL) { +		printf("Block device %s %d not supported\n", argv[1], dev); +		return 1; +	} + +	addr = (void *)simple_strtoul(argv[3], NULL, 16); +	blk = simple_strtoul(argv[4], NULL, 16); +	cnt = simple_strtoul(argv[5], NULL, 16); + +	if (part != 0) { +		if (get_partition_info(dev_desc, part, &part_info)) { +			printf("Cannot find partition %d\n", part); +			return 1; +		} +		offset = part_info.start; +		limit = part_info.size; +	} else { +		/* Largest address not available in block_dev_desc_t. */ +		limit = ~0; +	} + +	if (cnt + blk > limit) { +		printf("Read out of range\n"); +		return 1; +	} + +	if (dev_desc->block_read(dev, offset + blk, cnt, addr) < 0) { +		printf("Error reading blocks\n"); +		return 1; +	} + +	return 0; +} + +U_BOOT_CMD( +	read,	6,	0,	do_read, +	"Load binary data from a partition", +	"<interface> <dev[:part]> addr blk# cnt" +); |