From: jason@lakedaemon.net (Jason Cooper)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC PATCH V2 9/9] appended dtbs works!
Date: Fri, 2 Aug 2013 15:51:16 +0000 [thread overview]
Message-ID: <ecbf213c41cfd68781dd362e01ee1e42e3d7dba9.1375457714.git.jason@lakedaemon.net> (raw)
In-Reply-To: <cover.1375457714.git.jason@lakedaemon.net>
With this commit, the user can build a single binary with the zImage
linked in and the dtbs appended.
The user needs to provide a board-*.c file, address of the uart, then:
make MFG=boardname APPEND_KERNEL=/tmp/zImage APPEND_DTBS=/tmp/*.dtb \
uImage
Look at board-raumfeld.c for an example of how to determine the board
you are on and set the desired compatible string.
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
---
Makefile | 1 +
board-dreamplug.c | 28 ++++++++++++++++++++++++
board-raumfeld.c | 49 ++++++++++++++++++++----------------------
board.h | 2 --
dtbs.c | 36 +++++++++++++++++++++++++++++++
dtbs.h | 6 ++++++
endian.h | 12 +++++++++++
fdt.h | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
string.c | 10 +++++++++
string.h | 1 +
types.h | 1 +
11 files changed, 182 insertions(+), 28 deletions(-)
create mode 100644 board-dreamplug.c
create mode 100644 dtbs.c
create mode 100644 dtbs.h
create mode 100644 endian.h
create mode 100644 fdt.h
diff --git a/Makefile b/Makefile
index c9b2381..7829a01 100644
--- a/Makefile
+++ b/Makefile
@@ -25,6 +25,7 @@ BOARD_OBJ = board-$(MFG).o
UART_OBJ = serial-$(UART).o
COMMON_OBJS = \
+ dtbs.o \
main.o \
print.o \
register.o \
diff --git a/board-dreamplug.c b/board-dreamplug.c
new file mode 100644
index 0000000..123c0f4
--- /dev/null
+++ b/board-dreamplug.c
@@ -0,0 +1,28 @@
+#include "board.h"
+#include "dtbs.h"
+#include "print.h"
+#include "register.h"
+#include "types.h"
+
+/*
+ * this code is just a quick PoC for appending multiple dtbs. I don't have
+ * any boards handy with stock, non-DT bootloaders, so I have no machids to
+ * trigger off of.
+ */
+
+extern __u32 _binary_input_zImage_start;
+extern __u32 __end_of_image;
+
+struct board board;
+const char *compat = "globalscale,dreamplug";
+
+struct board *match_board(__u32 machid, const struct tag *tags)
+{
+
+ /* testing zImage linked in and dtbs appended */
+ board.kernel = &_binary_input_zImage_start;
+ board.compatible = compat;
+ board.dtb = find_dtb(&__end_of_image, compat);
+
+ return &board;
+}
diff --git a/board-raumfeld.c b/board-raumfeld.c
index e5d4702..90fffeb 100644
--- a/board-raumfeld.c
+++ b/board-raumfeld.c
@@ -1,38 +1,36 @@
#include "atags.h"
#include "board.h"
+#include "dtbs.h"
#include "print.h"
#include "register.h"
#include "types.h"
extern __u32 _binary_input_zImage_start;
-extern __u32 _binary_input_raumfeld_controller_0_dtb_start;
-extern __u32 _binary_input_raumfeld_controller_1_dtb_start;
-extern __u32 _binary_input_raumfeld_controller_2_dtb_start;
-extern __u32 _binary_input_raumfeld_connector_0_dtb_start;
-extern __u32 _binary_input_raumfeld_connector_1_dtb_start;
-extern __u32 _binary_input_raumfeld_connector_2_dtb_start;
-extern __u32 _binary_input_raumfeld_speaker_0_dtb_start;
-extern __u32 _binary_input_raumfeld_speaker_1_dtb_start;
-extern __u32 _binary_input_raumfeld_speaker_2_dtb_start;
-
-static struct board boards[] = {
+extern __u32 __end_of_image;
+
+struct board board;
+
+struct raum_board {
+ __u32 machid;
+ __u32 system_rev;
+ const char *compatible;
+};
+
+static struct raum_board rboards[] = {
/* Controller */
{
.machid = 2413,
.system_rev = 0,
- .dtb = &_binary_input_raumfeld_controller_0_dtb_start,
.compatible = "Raumfeld Controller, revision 0",
},
{
.machid = 2413,
.system_rev = 1,
- .dtb = &_binary_input_raumfeld_controller_1_dtb_start,
.compatible = "Raumfeld Controller, revision 1",
},
{
.machid = 2413,
.system_rev = 2,
- .dtb = &_binary_input_raumfeld_controller_2_dtb_start,
.compatible = "Raumfeld Controller, revision 2",
},
@@ -40,19 +38,16 @@ static struct board boards[] = {
{
.machid = 2414,
.system_rev = 0,
- .dtb = &_binary_input_raumfeld_connector_0_dtb_start,
.compatible = "Raumfeld Connector, revision 0",
},
{
.machid = 2414,
.system_rev = 1,
- .dtb = &_binary_input_raumfeld_connector_1_dtb_start,
.compatible = "Raumfeld Connector, revision 1",
},
{
.machid = 2414,
.system_rev = 2,
- .dtb = &_binary_input_raumfeld_connector_2_dtb_start,
.compatible = "Raumfeld Connector, revision 2",
},
@@ -60,22 +55,19 @@ static struct board boards[] = {
{
.machid = 2415,
.system_rev = 0,
- .dtb = &_binary_input_raumfeld_speaker_0_dtb_start,
.compatible = "Raumfeld Speaker, revision 0",
},
{
.machid = 2415,
.system_rev = 1,
- .dtb = &_binary_input_raumfeld_speaker_1_dtb_start,
.compatible = "Raumfeld Speaker, revision 1",
},
{
.machid = 2415,
.system_rev = 2,
- .dtb = &_binary_input_raumfeld_speaker_2_dtb_start,
.compatible = "Raumfeld Speaker, revision 2",
},
- { 0, 0, NULL, NULL } /* sentinel */
+ { 0, 0, NULL } /* sentinel */
};
static void wait(__u32 ticks)
@@ -122,7 +114,7 @@ static void led_panic(void)
struct board *match_board(__u32 machid, const struct tag *tags)
{
const struct tag *t;
- struct board *board;
+ struct raum_board *rboard;
__u32 system_rev = 0;
/* walk the atags to determine the system revision */
@@ -134,11 +126,12 @@ struct board *match_board(__u32 machid, const struct tag *tags)
}
- for (board = boards; board->machid; board++)
- if (board->machid == machid && board->system_rev == system_rev)
+ for (rboard = rboards; rboard->machid; rboard++)
+ if (rboard->machid == machid &&
+ rboard->system_rev == system_rev)
break;
- if (board->compatible == NULL) {
+ if (rboard->compatible == NULL) {
putstr("ERROR MATCHING BOARD!\n");
putstr("MACHID: 0x");
printhex(machid);
@@ -149,5 +142,9 @@ struct board *match_board(__u32 machid, const struct tag *tags)
led_panic(); /* doesn't return */
}
- return board;
+ board.kernel = &_binary_input_zImage_start;
+ board.compatible = rboard->compatible;
+ board.dtb = find_dtb(&__end_of_image, rboard->compatible);
+
+ return &board;
}
diff --git a/board.h b/board.h
index a28fb06..75931a1 100644
--- a/board.h
+++ b/board.h
@@ -5,8 +5,6 @@
#include "atags.h"
struct board {
- __u32 machid;
- __u32 system_rev;
void *dtb;
void *kernel;
const char *compatible;
diff --git a/dtbs.c b/dtbs.c
new file mode 100644
index 0000000..a761ac4
--- /dev/null
+++ b/dtbs.c
@@ -0,0 +1,36 @@
+#include "endian.h"
+#include "fdt.h"
+#include "print.h"
+#include "string.h"
+#include "types.h"
+
+/* Yes, this is a dirty hack. But it's simple, and fast. */
+
+int find_str(char *mem, __u32 memsz, const char *str)
+{
+ __u32 len = strlen(str);
+ const char *last = mem + memsz - len;
+ const char *p;
+
+ for (p = mem; p < last; p++) {
+ if (*p == *str)
+ if (strncmp(p, str, len) == 0)
+ return 1;
+ }
+
+ return 0;
+}
+
+void *find_dtb(void *dtbs, const char *compat)
+{
+ struct fdt_header *d = (struct fdt_header *)dtbs;
+
+ while (d->magic == be_to_cpu(FDT_MAGIC)) {
+ if (find_str((char *)d, be_to_cpu(d->totalsize), compat) == 1)
+ break;
+
+ d = (struct fdt_header *)((char *)d + be_to_cpu(d->totalsize));
+ }
+
+ return d;
+}
diff --git a/dtbs.h b/dtbs.h
new file mode 100644
index 0000000..4e14b32
--- /dev/null
+++ b/dtbs.h
@@ -0,0 +1,6 @@
+#ifndef _DTBS_H
+#define _DTBS_H
+
+void *find_dtb(void *, const char *);
+
+#endif
diff --git a/endian.h b/endian.h
new file mode 100644
index 0000000..531b6b1
--- /dev/null
+++ b/endian.h
@@ -0,0 +1,12 @@
+#ifndef _ENDIAN_H
+#define _ENDIAN_H
+
+#include "types.h"
+
+#define be_to_cpu(x) \
+ ( ((0xFF000000UL & ((__u32)x)) >> 24) | \
+ ((0x00FF0000UL & ((__u32)x)) >> 8) | \
+ ((0x0000FF00UL & ((__u32)x)) << 8) | \
+ ((0x000000FFUL & ((__u32)x)) << 24) )
+
+#endif
diff --git a/fdt.h b/fdt.h
new file mode 100644
index 0000000..13a0354
--- /dev/null
+++ b/fdt.h
@@ -0,0 +1,64 @@
+#ifndef _FDT_H
+#define _FDT_H
+
+/* Copied from barebox, thanks! */
+
+#include "types.h"
+
+#ifndef __ASSEMBLY__
+
+struct fdt_header {
+ __u32 magic; /* magic word FDT_MAGIC */
+ __u32 totalsize; /* total size of DT block */
+ __u32 off_dt_struct; /* offset to structure */
+ __u32 off_dt_strings; /* offset to strings */
+ __u32 off_mem_rsvmap; /* offset to memory reserve map */
+ __u32 version; /* format version */
+ __u32 last_comp_version; /* last compatible version */
+
+ /* version 2 fields below */
+ __u32 boot_cpuid_phys; /* Which physical CPU id we're
+ booting on */
+ /* version 3 fields below */
+ __u32 size_dt_strings; /* size of the strings block */
+
+ /* version 17 fields below */
+ __u32 size_dt_struct; /* size of the structure block */
+} __attribute__((packed));
+
+struct fdt_reserve_entry {
+ __u64 address;
+ __u64 size;
+};
+
+struct fdt_node_header {
+ __u32 tag;
+ char name[0];
+};
+
+struct fdt_property {
+ __u32 tag;
+ __u32 len;
+ __u32 nameoff;
+ char data[0];
+};
+
+#endif /* !__ASSEMBLY */
+
+#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */
+#define FDT_TAGSIZE sizeof(__u32)
+
+#define FDT_BEGIN_NODE 0x1 /* Start node: full name */
+#define FDT_END_NODE 0x2 /* End node */
+#define FDT_PROP 0x3 /* Property: name off,
+ size, content */
+#define FDT_NOP 0x4 /* nop */
+#define FDT_END 0x9
+
+#define FDT_V1_SIZE (7*sizeof(__u32))
+#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(__u32))
+#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(__u32))
+#define FDT_V16_SIZE FDT_V3_SIZE
+#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(__u32))
+
+#endif /* _FDT_H */
diff --git a/string.c b/string.c
index 6584378..d13e22b 100644
--- a/string.c
+++ b/string.c
@@ -7,6 +7,16 @@ int hexlut[1 + 'F' - '0'] = {
0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* A - F */
};
+int strlen(const char *str)
+{
+ const char *c = str;
+
+ while (*(c++))
+ ;
+
+ return c - str;
+}
+
int strncmp(const char *stra, const char *strb, int len)
{
int diff=0;
diff --git a/string.h b/string.h
index 59f5f0c..0b99785 100644
--- a/string.h
+++ b/string.h
@@ -1,6 +1,7 @@
#ifndef _STRING_H
#define _STRING_H
+int strlen(const char *);
int strncmp(const char *, const char *, int);
void *gethexaddr(const char *, const char **);
int getaddrs(void **, void **, const char *);
diff --git a/types.h b/types.h
index 27ec08e..4c078a3 100644
--- a/types.h
+++ b/types.h
@@ -2,6 +2,7 @@
#define _TYPES_H
typedef unsigned int __u32;
+typedef unsigned long long __u64;
#define NULL ((void *) 0)
#endif /* _TYPES_H */
--
1.8.3.2
next prev parent reply other threads:[~2013-08-02 15:51 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-07-04 16:56 Appended DTB files for multi-machine kernels Daniel Mack
2013-07-04 17:11 ` Mark Brown
2013-07-04 21:34 ` Arnd Bergmann
2013-07-04 23:02 ` Daniel Mack
2013-07-05 8:32 ` Magnus Damm
2013-07-04 17:28 ` Nicolas Pitre
2013-07-04 17:57 ` Daniel Mack
2013-07-04 18:27 ` Nicolas Pitre
2013-07-26 16:13 ` Daniel Mack
2013-07-26 16:44 ` Nicolas Pitre
2013-07-29 21:23 ` [RFC PATCH 0/2] impedance-matcher generic improvements Jason Cooper
2013-07-29 21:24 ` [PATCH 1/2] add cscope Makefile target Jason Cooper
2013-07-29 21:24 ` [RFC PATCH 2/2] WIP: Get kernel and dtb addresses from command line Jason Cooper
2013-07-30 7:48 ` [RFC PATCH 0/2] impedance-matcher generic improvements Daniel Mack
2013-07-30 13:17 ` Jason Cooper
2013-07-30 13:37 ` Daniel Mack
2013-07-30 14:42 ` Jason Cooper
2013-08-02 15:51 ` [RFC PATCH V2 0/9] " Jason Cooper
2013-08-02 15:51 ` [RFC PATCH V2 1/9] add cscope Makefile target Jason Cooper
2013-08-02 15:51 ` [RFC PATCH V2 2/9] separate common functions from board specific Jason Cooper
2013-08-02 15:51 ` [RFC PATCH V2 3/9] rename board.c to board-raumfeld.c Jason Cooper
2013-08-02 15:51 ` [RFC PATCH V2 4/9] s/.name/.compatible/ Jason Cooper
2013-08-02 21:52 ` Stephen Warren
2013-08-03 14:07 ` Jason Cooper
2013-08-03 14:16 ` Daniel Mack
2013-08-02 15:51 ` [RFC PATCH V2 5/9] directly include needed headers Jason Cooper
2013-08-02 15:51 ` [RFC PATCH V2 6/9] serial: split out 8250 code, configurable reg addr Jason Cooper
2013-08-02 15:51 ` [RFC PATCH V2 7/9] add generic board code Jason Cooper
2013-08-02 15:51 ` [RFC PATCH V2 8/9] make appending images/dtbs optional Jason Cooper
2013-08-02 15:51 ` Jason Cooper [this message]
2013-08-02 19:42 ` [RFC PATCH V2 9/9] appended dtbs works! Nicolas Pitre
2013-08-02 19:54 ` Jason Cooper
2013-08-02 19:57 ` Jason Cooper
2013-08-02 17:53 ` [RFC PATCH V2 0/9] impedance-matcher generic improvements Daniel Mack
2013-08-02 18:43 ` Jason Cooper
2013-08-02 18:46 ` Daniel Mack
2013-07-04 18:36 ` Appended DTB files for multi-machine kernels Dirk Behme
2013-07-05 18:36 ` Stephen Warren
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ecbf213c41cfd68781dd362e01ee1e42e3d7dba9.1375457714.git.jason@lakedaemon.net \
--to=jason@lakedaemon.net \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).