diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2008-06-11 11:58:39 +1000 |
---|---|---|
committer | Jon Loeliger <jdl@jdl.com> | 2008-06-19 10:01:14 -0500 |
commit | e37ec7d5889fa04047daaa7a4ff55150ed7954d4 (patch) | |
tree | 152581799010da82ee7b792e57636aa50e00c6e1 | |
parent | 050e6f0cff5b93a15fefbc0b554cad9a9ab5ea82 (diff) | |
download | dtc-e37ec7d5889fa04047daaa7a4ff55150ed7954d4.zip dtc-e37ec7d5889fa04047daaa7a4ff55150ed7954d4.tar.gz dtc-e37ec7d5889fa04047daaa7a4ff55150ed7954d4.tar.bz2 |
dtc: Add support for binary includes.
On Wed, Jun 04, 2008 at 09:26:23AM -0500, Jon Loeliger wrote:
> David Gibson wrote:
>
>> But as I said that can be dealt with in the future without breaking
>> compatibility. Objection withdrawn.
>>
>
> And on that note, I officially implore Scott to
> re-submit his binary include patch!
Scott's original patch does still have some implementation details I
didn't like. So in the interests of saving time, I've addressed some
of those, added a testcase, and and now resubmitting my revised
version of Scott's patch.
dtc: Add support for binary includes.
A property's data can be populated with a file's contents
as follows:
node {
prop = /incbin/("path/to/data");
};
A subset of a file can be included by passing start and size parameters.
For example, to include bytes 8 through 23:
node {
prop = /incbin/("path/to/data", 8, 16);
};
As with /include/, non-absolute paths are looked for in the directory
of the source file that includes them.
Implementation revised, and a testcase added by David Gibson
Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Acked-by: Scott Wood <scottwood@freescale.com>
-rw-r--r-- | data.c | 25 | ||||
-rw-r--r-- | dtc-lexer.l | 7 | ||||
-rw-r--r-- | dtc-parser.y | 31 | ||||
-rw-r--r-- | tests/Makefile.tests | 2 | ||||
-rw-r--r-- | tests/incbin.bin | 1 | ||||
-rw-r--r-- | tests/incbin.c | 75 | ||||
-rw-r--r-- | tests/incbin.dts | 6 | ||||
-rwxr-xr-x | tests/run_tests.sh | 4 |
8 files changed, 145 insertions, 6 deletions
@@ -167,14 +167,29 @@ struct data data_copy_escape_string(const char *s, int len) return d; } -struct data data_copy_file(FILE *f, size_t len) +struct data data_copy_file(FILE *f, size_t maxlen) { - struct data d; + struct data d = empty_data; - d = data_grow_for(empty_data, len); + while (!feof(f) && (d.len < maxlen)) { + size_t chunksize, ret; - d.len = len; - fread(d.val, len, 1, f); + if (maxlen == -1) + chunksize = 4096; + else + chunksize = maxlen - d.len; + + d = data_grow_for(d, chunksize); + ret = fread(d.val + d.len, 1, chunksize, f); + + if (ferror(f)) + die("Error reading file into data: %s", strerror(errno)); + + if (d.len + ret < d.len) + die("Overflow reading file into data\n"); + + d.len += ret; + } return d; } diff --git a/dtc-lexer.l b/dtc-lexer.l index 04b1753..8f15c4d 100644 --- a/dtc-lexer.l +++ b/dtc-lexer.l @@ -190,6 +190,13 @@ static int pop_input_file(void); return DT_PROPNODENAME; } +"/incbin/" { + yylloc.file = srcpos_file; + yylloc.first_line = yylineno; + DPRINT("Binary Include\n"); + return DT_INCBIN; + } + <*>[[:space:]]+ /* eat whitespace */ <*>"/*"([^*]|\*+[^*/])*\*+"/" { diff --git a/dtc-parser.y b/dtc-parser.y index 0bf3fcb..8d04e49 100644 --- a/dtc-parser.y +++ b/dtc-parser.y @@ -21,6 +21,8 @@ %locations %{ +#include <stdio.h> + #include "dtc.h" #include "srcpos.h" @@ -59,6 +61,7 @@ static unsigned long long eval_literal(const char *s, int base, int bits); %token <data> DT_STRING %token <labelref> DT_LABEL %token <labelref> DT_REF +%token DT_INCBIN %type <data> propdata %type <data> propdataprefix @@ -197,6 +200,34 @@ propdata: { $$ = data_add_marker($1, REF_PATH, $2); } + | propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')' + { + struct search_path path = { srcpos_file->dir, NULL, NULL }; + struct dtc_file *file = dtc_open_file($4.val, &path); + struct data d = empty_data; + + if ($6 != 0) + if (fseek(file->file, $6, SEEK_SET) != 0) + yyerrorf("Couldn't seek to offset %llu in \"%s\": %s", + (unsigned long long)$6, + $4.val, strerror(errno)); + + d = data_copy_file(file->file, $8); + + $$ = data_merge($1, d); + dtc_close_file(file); + } + | propdataprefix DT_INCBIN '(' DT_STRING ')' + { + struct search_path path = { srcpos_file->dir, NULL, NULL }; + struct dtc_file *file = dtc_open_file($4.val, &path); + struct data d = empty_data; + + d = data_copy_file(file->file, -1); + + $$ = data_merge($1, d); + dtc_close_file(file); + } | propdata DT_LABEL { $$ = data_add_marker($1, LABEL, $2); diff --git a/tests/Makefile.tests b/tests/Makefile.tests index cb57ac0..704c95d 100644 --- a/tests/Makefile.tests +++ b/tests/Makefile.tests @@ -9,7 +9,7 @@ LIB_TESTS_L = get_mem_rsv \ sw_tree1 \ move_and_save mangle-layout nopulate \ open_pack rw_tree1 set_name setprop del_property del_node \ - string_escapes references path-references boot-cpuid \ + string_escapes references path-references boot-cpuid incbin \ dtbs_equal_ordered \ add_subnode_with_nops LIB_TESTS = $(LIB_TESTS_L:%=$(TESTS_PREFIX)%) diff --git a/tests/incbin.bin b/tests/incbin.bin new file mode 100644 index 0000000..e6e3e48 --- /dev/null +++ b/tests/incbin.bin @@ -0,0 +1 @@ +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
\ No newline at end of file diff --git a/tests/incbin.c b/tests/incbin.c new file mode 100644 index 0000000..2f8a55a --- /dev/null +++ b/tests/incbin.c @@ -0,0 +1,75 @@ +/* + * libfdt - Flat Device Tree manipulation + * Testcase for string escapes in dtc + * Copyright (C) 2006 David Gibson, IBM Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdint.h> +#include <errno.h> + +#include <fdt.h> +#include <libfdt.h> + +#include "tests.h" +#include "testdata.h" + +#define CHUNKSIZE 1024 + +void *load_file(const char *name, int *len) +{ + FILE *f; + void *buf = NULL; + int bufsize = 0, n; + + *len = 0; + + f = fopen(name, "r"); + if (!f) + FAIL("Couldn't open \"%s\": %s", name, strerror(errno)); + + while (!feof(f)) { + if (bufsize < (*len + CHUNKSIZE)) { + buf = xrealloc(buf, *len + CHUNKSIZE); + bufsize = *len + CHUNKSIZE; + } + + n = fread(buf + *len, 1, CHUNKSIZE, f); + if (ferror(f)) + FAIL("Error reading \"%s\": %s", name, strerror(errno)); + *len += n; + } + + return buf; +} + +int main(int argc, char *argv[]) +{ + void *fdt, *incbin; + int len; + + test_init(argc, argv); + + incbin = load_file("incbin.bin", &len); + fdt = load_blob_arg(argc, argv); + + check_getprop(fdt, 0, "incbin", len, incbin); + check_getprop(fdt, 0, "incbin-partial", 17, incbin + 13); + + PASS(); +} diff --git a/tests/incbin.dts b/tests/incbin.dts new file mode 100644 index 0000000..7c30e0e --- /dev/null +++ b/tests/incbin.dts @@ -0,0 +1,6 @@ +/dts-v1/; + +/ { + incbin = /incbin/("incbin.bin"); + incbin-partial = /incbin/("incbin.bin", 13, 17); +}; diff --git a/tests/run_tests.sh b/tests/run_tests.sh index 72efc08..3b78f8d 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -206,6 +206,10 @@ dtc_tests () { run_dtc_test -I dts -O dtb -o dtc_comments-cmp.test.dtb comments-cmp.dts run_test dtbs_equal_ordered dtc_comments.test.dtb dtc_comments-cmp.test.dtb + # Check /incbin/ directive + run_dtc_test -I dts -O dtb -o incbin.test.dtb incbin.dts + run_test incbin incbin.test.dtb + # Check boot_cpuid_phys handling run_dtc_test -I dts -O dtb -b 17 -o boot_cpuid.test.dtb empty.dts run_test boot-cpuid boot_cpuid.test.dtb 17 |