@@ -18,7 +18,8 @@ UART_OBJ = serial-$(UART).o
COMMON_OBJS = \
main.o \
print.o \
- register.o
+ register.o \
+ string.o
INPUT_OBJS = \
zimage.o \
@@ -17,10 +17,18 @@ struct tag_revision {
__u32 rev;
};
+/* command line */
+#define ATAG_CMDLINE 0x54410009
+
+struct tag_cmdline {
+ char cmdline[1]; /* this is the minimum size */
+};
+
struct tag {
struct tag_header hdr;
union {
struct tag_revision rev;
+ struct tag_cmdline cmdline;
} u;
};
new file mode 100644
@@ -0,0 +1,39 @@
+#include "atags.h"
+#include "board.h"
+#include "print.h"
+#include "types.h"
+#include "string.h"
+
+struct board genboard;
+
+struct board *match_board(__u32 machid, const struct tag *tags)
+{
+ const struct tag *t;
+
+ /* walk the atags to get the command line */
+ for_each_tag(t, tags)
+ switch (t->hdr.tag) {
+ case ATAG_CMDLINE:
+ getaddrs(&genboard.kernel, &genboard.dtb,
+ t->u.cmdline.cmdline);
+ break;
+ }
+
+ if (genboard.kernel) {
+ putstr("Kernel: 0x");
+ printhex((__u32)genboard.kernel);
+ } else
+ putstr("Kernel: Appended");
+ putstr("\n");
+
+ if (genboard.dtb) {
+ putstr("DTB: 0x");
+ printhex((__u32)genboard.dtb);
+ } else
+ putstr("** DTB Not Found! **");
+ putstr("\n");
+
+ genboard.compatible = NULL;
+
+ return &genboard;
+}
@@ -8,6 +8,7 @@ struct board {
__u32 machid;
__u32 system_rev;
void *dtb;
+ void *kernel;
const char *compatible;
};
@@ -20,7 +20,10 @@ void main(__u32 dummy, __u32 machid, const struct tag *tags)
board = match_board(machid, tags);
putstr("Detected board: ");
- putstr(board->compatible);
+ if (board->compatible)
+ putstr(board->compatible);
+ else
+ putstr("Not given.");
putstr("\n");
putstr("Booting into Linux kernel ...\n");
new file mode 100644
@@ -0,0 +1,89 @@
+#include "types.h"
+#include "string.h"
+
+int hexlut[1 + 'F' - '0'] = {
+ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, /* 0 - 9 */
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* A - F */
+};
+
+int strncmp(const char *stra, const char *strb, int len)
+{
+ int diff=0;
+ const char *a = stra;
+ const char *b = strb;
+
+ while ((a - stra) < len)
+ diff += *(a++) - *(b++);
+
+ return diff;
+}
+
+void *gethexaddr(const char *str, const char **end)
+{
+ const char *s = str;
+ char *e;
+ void *addr = NULL;
+ int shift = 0;
+
+ /* set the end */
+ while (*s) {
+ if (*s == ' ' || *s == '\t' || *s == ',')
+ break;
+ s++;
+ }
+
+ if (!*s)
+ return NULL;
+
+ e = (char *)s;
+ s = (const char *)(e - 1);
+
+ while (s >= str && *s != 'x') {
+ /* we assume base16! */
+ int off = (*s > 'F') ? 0x20 : 0x0;
+ addr += hexlut[*s - ('0' + off)] << shift;
+ shift += 4;
+ s--;
+ }
+
+ if (end)
+ *end = e;
+
+ return addr;
+}
+
+int getaddrs(void **k, void **d, const char *str)
+{
+ const char *s = str;
+ const char *end;
+
+ while (*s) {
+ if (*s == 'l')
+ if (strncmp(s, "loadaddrs=", 10) == 0)
+ break;
+
+ s++;
+ }
+
+ if (!*s)
+ return -1;
+
+ s += 10; /* skip over 'loadaddrs=' */
+
+ /* allow address to be 'appended' for some use cases */
+ if (strncmp(s, "appended", 8) == 0) {
+ *k = NULL;
+ end = s + 8;
+ } else
+ *k = gethexaddr(s, &end);
+
+ if (*end == ',')
+ s = end + 1;
+ else
+ return -1;
+
+ *d = gethexaddr(s, NULL);
+
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,8 @@
+#ifndef _STRING_H
+#define _STRING_H
+
+int strncmp(const char *, const char *, int);
+void *gethexaddr(const char *, const char **);
+int getaddrs(void **, void **, const char *);
+
+#endif
Signed-off-by: Jason Cooper <jason@lakedaemon.net> --- Makefile | 3 +- atags.h | 8 ++++++ board-generic.c | 39 +++++++++++++++++++++++++ board.h | 1 + main.c | 5 +++- string.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ string.h | 8 ++++++ 7 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 board-generic.c create mode 100644 string.c create mode 100644 string.h