Skip to content

Commit

Permalink
Support 'r' format for printing raw bytes with fdtget
Browse files Browse the repository at this point in the history
FT is sometimes used for storing raw data. That is quite common for
U-Boot FIT images.

Extracting such data is not trivial currently. Using type 's' (string)
will replace every 0x00 (NUL) with 0x20 (space). Using type 'x' will
print bytes but in xxd incompatible format.

This commit adds support for 'r' (raw) format. Example usage:
fdtget -t r firmware.itb /images/foo data > image.raw

Support for encoding isn't added as there isn't any clean way of passing
binary data as command line argument.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Message-Id: <20211209061420.29466-1-zajec5@gmail.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
  • Loading branch information
Rafał Miłecki authored and dgibson committed Dec 9, 2021
1 parent 45f3d1a commit 17739b7
Show file tree
Hide file tree
Showing 7 changed files with 18 additions and 5 deletions.
2 changes: 1 addition & 1 deletion Documentation/manual.txt
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,7 @@ The syntax of the fdtget command is:

where options are:

<type> s=string, i=int, u=unsigned, x=hex
<type> s=string, i=int, u=unsigned, x=hex, r=raw
Optional modifier prefix:
hh or b=byte, h=2 byte, l=4 byte (default)

Expand Down
5 changes: 5 additions & 0 deletions fdtget.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,11 @@ static int show_data(struct display_info *disp, const char *data, int len)
if (len == 0)
return 0;

if (disp->type == 'r') {
fwrite(data, 1, len, stdout);
return 0;
}

is_string = (disp->type) == 's' ||
(!disp->type && util_is_printable_string(data, len));
if (is_string) {
Expand Down
2 changes: 2 additions & 0 deletions fdtput.c
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,8 @@ int main(int argc, char *argv[])
if (utilfdt_decode_type(optarg, &disp.type,
&disp.size))
usage("Invalid type string");
if (disp.type == 'r')
usage("Unsupported raw data type");
break;

case 'v':
Expand Down
2 changes: 2 additions & 0 deletions tests/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -855,6 +855,8 @@ fdtget_tests () {
run_fdtget_test 8000 -tx $dtb /cpus/PowerPC,970@1 d-cache-size
run_fdtget_test "61 62 63 0" -tbx $dtb /randomnode tricky1
run_fdtget_test "a b c d de ea ad be ef" -tbx $dtb /randomnode blob
run_fdtget_test "MyBoardName\0MyBoardFamilyName\0" -tr $dtb / compatible
run_fdtget_test "\x0a\x0b\x0c\x0d\xde\xea\xad\xbe\xef" -tr $dtb /randomnode blob

# Here the property size is not a multiple of 4 bytes, so it should fail
run_wrap_error_test $DTGET -tlx $dtb /randomnode mixed
Expand Down
5 changes: 4 additions & 1 deletion tests/utilfdt_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ static void check_sizes(char *modifier, int expected_size)

*ptr = 's';
check(fmt, 's', -1);

*ptr = 'r';
check(fmt, 'r', -1);
}

static void test_utilfdt_decode_type(void)
Expand All @@ -90,7 +93,7 @@ static void test_utilfdt_decode_type(void)
/* try every other character */
checkfail("");
for (ch = ' '; ch < 127; ch++) {
if (!strchr("iuxs", ch)) {
if (!strchr("iuxsr", ch)) {
*fmt = ch;
fmt[1] = '\0';
checkfail(fmt);
Expand Down
4 changes: 2 additions & 2 deletions util.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,11 +353,11 @@ int utilfdt_decode_type(const char *fmt, int *type, int *size)
}

/* we should now have a type */
if ((*fmt == '\0') || !strchr("iuxs", *fmt))
if ((*fmt == '\0') || !strchr("iuxsr", *fmt))
return -1;

/* convert qualifier (bhL) to byte size */
if (*fmt != 's')
if (*fmt != 's' && *fmt != 'r')
*size = qualifier == 'b' ? 1 :
qualifier == 'h' ? 2 :
qualifier == 'l' ? 4 : -1;
Expand Down
3 changes: 2 additions & 1 deletion util.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ int utilfdt_write_err(const char *filename, const void *blob);
* i signed integer
* u unsigned integer
* x hex
* r raw
*
* TODO: Implement ll modifier (8 bytes)
* TODO: Implement o type (octal)
Expand All @@ -160,7 +161,7 @@ int utilfdt_decode_type(const char *fmt, int *type, int *size);
*/

#define USAGE_TYPE_MSG \
"<type>\ts=string, i=int, u=unsigned, x=hex\n" \
"<type>\ts=string, i=int, u=unsigned, x=hex, r=raw\n" \
"\tOptional modifier prefix:\n" \
"\t\thh or b=byte, h=2 byte, l=4 byte (default)";
Expand Down

0 comments on commit 17739b7

Please sign in to comment.