svn commit: r276506 - user/nwhitehorn/kboot/powerpc/kboot
Nathan Whitehorn
nwhitehorn at FreeBSD.org
Thu Jan 1 18:07:59 UTC 2015
Author: nwhitehorn
Date: Thu Jan 1 18:07:56 2015
New Revision: 276506
URL: https://svnweb.freebsd.org/changeset/base/276506
Log:
Create FDT from /proc/device-tree on Linux host. This is enough to get into
KDB.
Added:
user/nwhitehorn/kboot/powerpc/kboot/kbootfdt.c (contents, props changed)
Modified:
user/nwhitehorn/kboot/powerpc/kboot/Makefile
user/nwhitehorn/kboot/powerpc/kboot/host_syscall.S
user/nwhitehorn/kboot/powerpc/kboot/host_syscall.h
user/nwhitehorn/kboot/powerpc/kboot/metadata.c
user/nwhitehorn/kboot/powerpc/kboot/ppc64_elf_freebsd.c
Modified: user/nwhitehorn/kboot/powerpc/kboot/Makefile
==============================================================================
--- user/nwhitehorn/kboot/powerpc/kboot/Makefile Thu Jan 1 16:56:15 2015 (r276505)
+++ user/nwhitehorn/kboot/powerpc/kboot/Makefile Thu Jan 1 18:07:56 2015 (r276506)
@@ -10,7 +10,7 @@ INSTALLFLAGS= -b
# Architecture-specific loader code
SRCS= conf.c metadata.c vers.c main.c ppc64_elf_freebsd.c
-SRCS+= host_syscall.S hostcons.c hostdisk.c kerneltramp.S
+SRCS+= host_syscall.S hostcons.c hostdisk.c kerneltramp.S kbootfdt.c
SRCS+= ucmpdi2.c
LOADER_DISK_SUPPORT?= yes
@@ -21,7 +21,7 @@ LOADER_NET_SUPPORT?= yes
LOADER_NFS_SUPPORT?= yes
LOADER_TFTP_SUPPORT?= no
LOADER_GZIP_SUPPORT?= yes
-LOADER_FDT_SUPPORT?= no
+LOADER_FDT_SUPPORT?= yes
LOADER_BZIP2_SUPPORT?= no
.if ${LOADER_DISK_SUPPORT} == "yes"
@@ -54,6 +54,7 @@ CFLAGS+= -DLOADER_TFTP_SUPPORT
.if ${LOADER_FDT_SUPPORT} == "yes"
CFLAGS+= -I${.CURDIR}/../../fdt
CFLAGS+= -I${.OBJDIR}/../../fdt
+CFLAGS+= -I${.CURDIR}/../../../contrib/libfdt
CFLAGS+= -DLOADER_FDT_SUPPORT
LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a
.endif
Modified: user/nwhitehorn/kboot/powerpc/kboot/host_syscall.S
==============================================================================
--- user/nwhitehorn/kboot/powerpc/kboot/host_syscall.S Thu Jan 1 16:56:15 2015 (r276505)
+++ user/nwhitehorn/kboot/powerpc/kboot/host_syscall.S Thu Jan 1 18:07:56 2015 (r276506)
@@ -3,6 +3,10 @@
ENTRY(host_read)
li %r0, 3 # SYS_read
sc
+ bso 1f
+ blr
+1:
+ li %r3, -1
blr
ENTRY(host_write)
@@ -60,3 +64,8 @@ ENTRY(host_reboot)
sc
blr
+ENTRY(host_getdents)
+ li %r0,141 # SYS_getdents
+ sc
+ blr
+
Modified: user/nwhitehorn/kboot/powerpc/kboot/host_syscall.h
==============================================================================
--- user/nwhitehorn/kboot/powerpc/kboot/host_syscall.h Thu Jan 1 16:56:15 2015 (r276505)
+++ user/nwhitehorn/kboot/powerpc/kboot/host_syscall.h Thu Jan 1 18:07:56 2015 (r276506)
@@ -46,5 +46,6 @@ int host_select(int nfds, long *readfds,
struct host_timeval *timeout);
int kexec_load(vm_offset_t start);
int host_reboot(int, int, int, void *);
+int host_getdents(int fd, void *dirp, int count);
#endif
Added: user/nwhitehorn/kboot/powerpc/kboot/kbootfdt.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ user/nwhitehorn/kboot/powerpc/kboot/kbootfdt.c Thu Jan 1 18:07:56 2015 (r276506)
@@ -0,0 +1,140 @@
+/*-
+ * Copyright (C) 2014 Nathan Whitehorn
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <fdt_platform.h>
+#include <libfdt.h>
+#include "bootstrap.h"
+#include "host_syscall.h"
+
+static void
+print_fdt(void *fdtp)
+{
+ int offset, depth, i;
+ const char *compat;
+
+ offset = fdt_path_offset(fdtp, "/");
+
+ for (depth = 0, offset = fdt_next_node(fdtp, offset, &depth);
+ offset >= 0; offset = fdt_next_node(fdtp, offset, &depth)) {
+ for (i = 1; i < depth; i++) printf("\t");
+ printf("%d: %s",offset, fdt_get_name(fdtp, offset, NULL));
+ compat = fdt_getprop(fdtp, offset, "compatible", NULL);
+ if (compat != NULL)
+ printf(" (%s)", compat);
+ printf("\n");
+ }
+}
+
+static void
+add_node_to_fdt(void *buffer, const char *path, int fdt_offset)
+{
+ int child_offset, fd, pfd, error, dentsize;
+ char subpath[512];
+ void *propbuf;
+ ssize_t proplen;
+
+ struct host_dent {
+ unsigned long d_fileno;
+ unsigned long d_off;
+ unsigned short d_reclen;
+ char d_name[];
+ /* uint8_t d_type; */
+ };
+ char dents[2048];
+ struct host_dent *dent;
+ int d_type;
+
+ fd = open(path, O_RDONLY);
+ while (1) {
+ dentsize = host_getdents(fd, dents, sizeof(dents));
+ if (dentsize <= 0)
+ break;
+ for (dent = (struct host_dent *)dents;
+ (char *)dent < dents + dentsize;
+ dent = (struct host_dent *)((void *)dent + dent->d_reclen)) {
+ sprintf(subpath, "%s/%s", path, dent->d_name);
+ if (strcmp(dent->d_name, ".") == 0 ||
+ strcmp(dent->d_name, "..") == 0)
+ continue;
+ d_type = *((char *)(dent) + dent->d_reclen - 1);
+ if (d_type == 4 /* DT_DIR */) {
+ child_offset = fdt_add_subnode(buffer, fdt_offset,
+ dent->d_name);
+ if (child_offset < 0) {
+ printf("Error %d adding node %s/%s, skipping\n",
+ child_offset, path, dent->d_name);
+ continue;
+ }
+
+ add_node_to_fdt(buffer, subpath, child_offset);
+ } else {
+ pfd = open(subpath, O_RDONLY);
+ propbuf = malloc(1024);
+ proplen = read(pfd, propbuf, 1024);
+ if (proplen < 0)
+ proplen = 0;
+ error = fdt_setprop(buffer, fdt_offset, dent->d_name,
+ propbuf, proplen);
+ free(propbuf);
+ close(pfd);
+ if (error)
+ printf("Error %d adding property %s to "
+ "node %d\n", error, dent->d_name,
+ fdt_offset);
+ }
+ }
+ }
+
+ close(fd);
+}
+
+int
+fdt_platform_load_dtb(void)
+{
+ void *buffer;
+ size_t buflen = 409600;
+ char path[255] = "/proc/device-tree";
+
+ buffer = malloc(buflen);
+ fdt_create_empty_tree(buffer, buflen);
+ add_node_to_fdt(buffer, path, fdt_path_offset(buffer, "/"));
+ fdt_pack(buffer);
+printf("Device tree is %d total bytes\n", fdt_totalsize(buffer));
+
+ fdt_load_dtb_addr(buffer);
+
+ return (0);
+}
+
+void
+fdt_platform_fixups(void)
+{
+
+}
+
Modified: user/nwhitehorn/kboot/powerpc/kboot/metadata.c
==============================================================================
--- user/nwhitehorn/kboot/powerpc/kboot/metadata.c Thu Jan 1 16:56:15 2015 (r276505)
+++ user/nwhitehorn/kboot/powerpc/kboot/metadata.c Thu Jan 1 18:07:56 2015 (r276506)
@@ -242,7 +242,7 @@ md_copymodules(vm_offset_t addr, int ker
* - Module metadata are formatted and placed in kernel space.
*/
int
-md_load_dual(char *args, vm_offset_t *modulep, int kern64)
+md_load_dual(char *args, vm_offset_t *modulep, vm_offset_t *dtb, int kern64)
{
struct preloaded_file *kfp;
struct preloaded_file *xp;
@@ -250,6 +250,7 @@ md_load_dual(char *args, vm_offset_t *mo
vm_offset_t kernend;
vm_offset_t addr;
vm_offset_t envp;
+ vm_offset_t fdtp;
vm_offset_t size;
uint64_t scratch64;
char *rootdevname;
@@ -285,6 +286,11 @@ md_load_dual(char *args, vm_offset_t *mo
/* pad to a page boundary */
addr = roundup(addr, PAGE_SIZE);
+ /* Copy out FDT */
+ size = fdt_copy(addr);
+ *dtb = fdtp = addr;
+ addr = roundup(addr + size, PAGE_SIZE);
+
kernend = 0;
kfp = file_findfile(NULL, kern64 ? "elf64 kernel" : "elf32 kernel");
if (kfp == NULL)
@@ -295,10 +301,13 @@ md_load_dual(char *args, vm_offset_t *mo
if (kern64) {
scratch64 = envp;
file_addmetadata(kfp, MODINFOMD_ENVP, sizeof scratch64, &scratch64);
+ scratch64 = fdtp;
+ file_addmetadata(kfp, MODINFOMD_DTBP, sizeof scratch64, &scratch64);
scratch64 = kernend;
file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof scratch64, &scratch64);
} else {
file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp);
+ file_addmetadata(kfp, MODINFOMD_DTBP, sizeof fdtp, &fdtp);
file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
}
@@ -320,14 +329,14 @@ md_load_dual(char *args, vm_offset_t *mo
}
int
-md_load(char *args, vm_offset_t *modulep)
+md_load(char *args, vm_offset_t *modulep, vm_offset_t *dtb)
{
- return (md_load_dual(args, modulep, 0));
+ return (md_load_dual(args, modulep, dtb, 0));
}
int
-md_load64(char *args, vm_offset_t *modulep)
+md_load64(char *args, vm_offset_t *modulep, vm_offset_t *dtb)
{
- return (md_load_dual(args, modulep, 1));
+ return (md_load_dual(args, modulep, dtb, 1));
}
Modified: user/nwhitehorn/kboot/powerpc/kboot/ppc64_elf_freebsd.c
==============================================================================
--- user/nwhitehorn/kboot/powerpc/kboot/ppc64_elf_freebsd.c Thu Jan 1 16:56:15 2015 (r276505)
+++ user/nwhitehorn/kboot/powerpc/kboot/ppc64_elf_freebsd.c Thu Jan 1 18:07:56 2015 (r276506)
@@ -62,7 +62,7 @@ int
ppc64_elf_exec(struct preloaded_file *fp)
{
struct file_metadata *fmp;
- vm_offset_t mdp;
+ vm_offset_t mdp, dtb;
Elf_Ehdr *e;
int error;
uint32_t *trampoline;
@@ -77,13 +77,13 @@ ppc64_elf_exec(struct preloaded_file *fp
trampoline = malloc(szkerneltramp);
memcpy(trampoline, &kerneltramp, szkerneltramp);
trampoline[2] = e->e_entry;
- trampoline[3] = 0; /* FDT */
trampoline[4] = 0; /* Phys. mem offset */
trampoline[5] = 0; /* OF entry point */
- if ((error = md_load64(fp->f_args, &mdp)) != 0)
+ if ((error = md_load64(fp->f_args, &mdp, &dtb)) != 0)
return (error);
+ trampoline[3] = dtb;
trampoline[6] = mdp;
trampoline[7] = sizeof(mdp);
printf("Kernel entry at %#jx ...\n", e->e_entry);
More information about the svn-src-user
mailing list