cmd: xxd: add new command

Add xxd command to print file content as hexdump to standard out

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Roger Knecht <rknecht@pm.me>
This commit is contained in:
Roger Knecht 2022-09-03 13:15:04 +00:00 committed by Tom Rini
parent 690a1d6948
commit 23c0df6e7c
10 changed files with 209 additions and 0 deletions

View File

@ -1519,6 +1519,13 @@ M: Max Filippov <jcmvbkbc@gmail.com>
S: Maintained S: Maintained
F: arch/xtensa/ F: arch/xtensa/
XXD
M: Roger Knecht <rknecht@pm.me>
S: Maintained
F: cmd/xxd.c
F: doc/usage/cmd/xxd.rst
F: test/py/tests/test_xxd/
THE REST THE REST
M: Tom Rini <trini@konsulko.com> M: Tom Rini <trini@konsulko.com>
L: u-boot@lists.denx.de L: u-boot@lists.denx.de

View File

@ -469,6 +469,11 @@ config CMD_XIMG
help help
Extract a part of a multi-image. Extract a part of a multi-image.
config CMD_XXD
bool "xxd"
help
Print file as hexdump to standard output
config CMD_SPL config CMD_SPL
bool "spl export - Export boot information for Falcon boot" bool "spl export - Export boot information for Falcon boot"
depends on SPL depends on SPL

View File

@ -185,6 +185,7 @@ obj-$(CONFIG_CMD_USB_SDP) += usb_gadget_sdp.o
obj-$(CONFIG_CMD_THOR_DOWNLOAD) += thordown.o obj-$(CONFIG_CMD_THOR_DOWNLOAD) += thordown.o
obj-$(CONFIG_CMD_VBE) += vbe.o obj-$(CONFIG_CMD_VBE) += vbe.o
obj-$(CONFIG_CMD_XIMG) += ximg.o obj-$(CONFIG_CMD_XIMG) += ximg.o
obj-$(CONFIG_CMD_XXD) += xxd.o
obj-$(CONFIG_CMD_YAFFS2) += yaffs2.o obj-$(CONFIG_CMD_YAFFS2) += yaffs2.o
obj-$(CONFIG_CMD_SPL) += spl.o obj-$(CONFIG_CMD_SPL) += spl.o
obj-$(CONFIG_CMD_W1) += w1.o obj-$(CONFIG_CMD_W1) += w1.o

85
cmd/xxd.c Normal file
View File

@ -0,0 +1,85 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2022
* Roger Knecht <rknecht@pm.de>
*/
#include <common.h>
#include <command.h>
#include <display_options.h>
#include <fs.h>
#include <malloc.h>
#include <mapmem.h>
static int do_xxd(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
char *ifname;
char *dev;
char *file;
char *buffer;
phys_addr_t addr;
loff_t file_size;
if (argc < 4)
return CMD_RET_USAGE;
ifname = argv[1];
dev = argv[2];
file = argv[3];
// check file exists
if (fs_set_blk_dev(ifname, dev, FS_TYPE_ANY))
return CMD_RET_FAILURE;
if (!fs_exists(file)) {
log_err("File does not exist: ifname=%s dev=%s file=%s\n", ifname, dev, file);
return CMD_RET_FAILURE;
}
// get file size
if (fs_set_blk_dev(ifname, dev, FS_TYPE_ANY))
return CMD_RET_FAILURE;
if (fs_size(file, &file_size)) {
log_err("Cannot read file size: ifname=%s dev=%s file=%s\n", ifname, dev, file);
return CMD_RET_FAILURE;
}
// allocate memory for file content
buffer = calloc(sizeof(char), file_size);
if (!buffer) {
log_err("Out of memory\n");
return CMD_RET_FAILURE;
}
// map pointer to system memory
addr = map_to_sysmem(buffer);
// read file to memory
if (fs_set_blk_dev(ifname, dev, FS_TYPE_ANY))
return CMD_RET_FAILURE;
if (fs_read(file, addr, 0, 0, &file_size)) {
log_err("Cannot read file: ifname=%s dev=%s file=%s\n", ifname, dev, file);
return CMD_RET_FAILURE;
}
// print file content
print_buffer(0, buffer, sizeof(char), file_size, 0);
free(buffer);
return 0;
}
#ifdef CONFIG_SYS_LONGHELP
static char xxd_help_text[] =
"<interface> <dev[:part]> <file>\n"
" - Print file from 'dev' on 'interface' as hexdump to standard output\n";
#endif
U_BOOT_CMD(xxd, 4, 1, do_xxd,
"Print file as hexdump to standard output",
xxd_help_text
);

View File

@ -55,6 +55,7 @@ CONFIG_CMD_READ=y
CONFIG_CMD_REMOTEPROC=y CONFIG_CMD_REMOTEPROC=y
CONFIG_CMD_SPI=y CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y CONFIG_CMD_USB=y
CONFIG_CMD_XXD=y
CONFIG_BOOTP_DNS2=y CONFIG_BOOTP_DNS2=y
CONFIG_CMD_TFTPPUT=y CONFIG_CMD_TFTPPUT=y
CONFIG_CMD_TFTPSRV=y CONFIG_CMD_TFTPSRV=y

View File

@ -61,6 +61,7 @@ CONFIG_CMD_MEM_SEARCH=y
CONFIG_CMD_MX_CYCLIC=y CONFIG_CMD_MX_CYCLIC=y
CONFIG_CMD_MEMTEST=y CONFIG_CMD_MEMTEST=y
CONFIG_CMD_UNZIP=y CONFIG_CMD_UNZIP=y
CONFIG_CMD_XXD=y
CONFIG_CMD_BIND=y CONFIG_CMD_BIND=y
CONFIG_CMD_DEMO=y CONFIG_CMD_DEMO=y
CONFIG_CMD_GPIO=y CONFIG_CMD_GPIO=y

50
doc/usage/cmd/xxd.rst Normal file
View File

@ -0,0 +1,50 @@
.. SPDX-License-Identifier: GPL-2.0+:
xxd command
===============
Synopsis
--------
::
xxd <interface> <dev[:part]> <file>
Description
-----------
The xxd command prints the file content as hexdump to standard out.
interface
interface for accessing the block device (mmc, sata, scsi, usb, ....)
dev
device number
part
partition number, defaults to 1
file
path to file
Example
-------
Here is the output for a example text file:
::
=> xxd mmc 0:1 hello
00000000: 68 65 6c 6c 6f 20 77 6f 72 6c 64 0a 00 01 02 03 hello world.....
00000010: 04 05 ..
=>
Configuration
-------------
The xxd command is only available if CONFIG_CMD_XXD=y.
Return value
------------
The return value $? is set to 0 (true) if the file is readable, otherwise it returns a non-zero error code.

View File

@ -72,6 +72,7 @@ Shell commands
cmd/true cmd/true
cmd/ums cmd/ums
cmd/wdt cmd/wdt
cmd/xxd
Booting OS Booting OS
---------- ----------

View File

@ -0,0 +1,35 @@
# SPDX-License-Identifier: GPL-2.0+
"""Fixture for xxd command test
"""
import os
import shutil
from subprocess import check_call, CalledProcessError
import pytest
@pytest.fixture(scope='session')
def xxd_data(u_boot_config):
"""Set up a file system to be used in xxd tests
Args:
u_boot_config -- U-boot configuration.
"""
mnt_point = u_boot_config.persistent_data_dir + '/test_xxd'
image_path = u_boot_config.persistent_data_dir + '/xxd.img'
try:
os.mkdir(mnt_point, mode = 0o755)
with open(mnt_point + '/hello', 'w', encoding = 'ascii') as file:
file.write('hello world\n\x00\x01\x02\x03\x04\x05')
check_call(f'virt-make-fs --partition=gpt --size=+1M --type=vfat {mnt_point} {image_path}',
shell=True)
yield image_path
except CalledProcessError:
pytest.skip('Setup failed')
finally:
shutil.rmtree(mnt_point)
os.remove(image_path)

View File

@ -0,0 +1,23 @@
# SPDX-License-Identifier: GPL-2.0+
""" Unit test for xxd command
"""
import pytest
@pytest.mark.boardspec('sandbox')
@pytest.mark.buildconfigspec('cmd_xxd')
def test_xxd(u_boot_console, xxd_data):
""" Unit test for xxd
Args:
u_boot_console -- U-Boot console
xxd_data -- Path to the disk image used for testing.
"""
response = u_boot_console.run_command_list([
f'host bind 0 {xxd_data}',
'xxd host 0 hello'])
assert '00000000: 68 65 6c 6c 6f 20 77 6f 72 6c 64 0a 00 01 02 03 hello world.....\r\r\n' + \
'00000010: 04 05 ..' \
in response