Initial loader(8) support for Flattened Device Tree.

o This is disabled by default for now, and can be enabled using WITH_FDT at
  build time.

o Tested with ARM and PowerPC.

Reviewed by:	imp
Sponsored by:	The FreeBSD Foundation
This commit is contained in:
Rafal Jaworowski 2010-05-25 15:21:39 +00:00
parent 4f1ca2a872
commit 04cb90189b
11 changed files with 1409 additions and 13 deletions

View File

@ -30,5 +30,6 @@
#define _MACHINE_METADATA_H_
#define MODINFOMD_BOOTINFO 0x1001
#define MODINFOMD_DTBP 0x1002
#endif /* !_MACHINE_METADATA_H_ */

View File

@ -18,6 +18,11 @@ LOADER_NFS_SUPPORT?= yes
LOADER_TFTP_SUPPORT?= no
LOADER_GZIP_SUPPORT?= no
LOADER_BZIP2_SUPPORT?= no
.if defined(WITH_FDT)
LOADER_FDT_SUPPORT= yes
.else
LOADER_FDT_SUPPORT= no
.endif
.if ${LOADER_DISK_SUPPORT} == "yes"
CFLAGS+= -DLOADER_DISK_SUPPORT
@ -46,6 +51,12 @@ CFLAGS+= -DLOADER_NFS_SUPPORT
.if ${LOADER_TFTP_SUPPORT} == "yes"
CFLAGS+= -DLOADER_TFTP_SUPPORT
.endif
.if ${LOADER_FDT_SUPPORT} == "yes"
CFLAGS+= -I${.CURDIR}/../../fdt
CFLAGS+= -I${.OBJDIR}/../../fdt
CFLAGS+= -DLOADER_FDT_SUPPORT
LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a
.endif
.if !defined(NO_FORTH)
# Enable BootForth
@ -79,8 +90,8 @@ CFLAGS+= -I${.OBJDIR}/../../uboot/lib
# where to get libstand from
CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/
DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBSTAND}
LDADD= ${LIBFICL} ${LIBUBOOT} -lstand
DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBSTAND}
LDADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} -lstand
vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version
sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}

View File

@ -3,5 +3,6 @@ $FreeBSD$
NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
file is important. Make sure the current version number is on line 6.
1.1: Flattened Device Tree blob support.
1.0: Added storage support. Booting from HDD, USB, etc. is now possible.
0.5: Initial U-Boot/arm version (netbooting only).

25
sys/boot/fdt/Makefile Normal file
View File

@ -0,0 +1,25 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../contrib/libfdt/
LIB= fdt
INTERNALLIB=
# Vendor sources of libfdt.
SRCS+= fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
# Loader's fdt commands extension sources.
SRCS+= fdt_loader_cmd.c
CFLAGS+= -I${.CURDIR}/../../contrib/libfdt/ -I${.CURDIR}/../common/ \
-I${.CURDIR}/../uboot/lib
CFLAGS+= -ffreestanding
.if ${MACHINE_ARCH} == "powerpc" || ${MACHINE_ARCH} == "arm"
CFLAGS+= -msoft-float
.endif
CFLAGS+= -Wformat -Wall
.include <bsd.lib.mk>

File diff suppressed because it is too large Load Diff

View File

@ -18,6 +18,11 @@ LOADER_NFS_SUPPORT?= yes
LOADER_TFTP_SUPPORT?= no
LOADER_GZIP_SUPPORT?= no
LOADER_BZIP2_SUPPORT?= no
.if defined(WITH_FDT)
LOADER_FDT_SUPPORT= yes
.else
LOADER_FDT_SUPPORT= no
.endif
.if ${LOADER_DISK_SUPPORT} == "yes"
CFLAGS+= -DLOADER_DISK_SUPPORT
@ -46,6 +51,12 @@ CFLAGS+= -DLOADER_NFS_SUPPORT
.if ${LOADER_TFTP_SUPPORT} == "yes"
CFLAGS+= -DLOADER_TFTP_SUPPORT
.endif
.if ${LOADER_FDT_SUPPORT} == "yes"
CFLAGS+= -I${.CURDIR}/../../fdt
CFLAGS+= -I${.OBJDIR}/../../fdt
CFLAGS+= -DLOADER_FDT_SUPPORT
LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a
.endif
.if !defined(NO_FORTH)
# Enable BootForth
@ -79,8 +90,8 @@ CFLAGS+= -I${.OBJDIR}/../../uboot/lib
# where to get libstand from
CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/
DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBSTAND}
LDADD= ${LIBFICL} ${LIBUBOOT} -lstand
DPADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} ${LIBSTAND}
LDADD= ${LIBFICL} ${LIBUBOOT} ${LIBFDT} -lstand
vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version
sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}

View File

@ -3,6 +3,7 @@ $FreeBSD$
NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
file is important. Make sure the current version number is on line 6.
1.1: Flattened Device Tree blob support.
1.0: Added storage support.
0.6: Integrated with the new U-Boot API
0.5: Full network functionality.

View File

@ -53,6 +53,10 @@ extern unsigned char __sbss_start[];
extern unsigned char __sbss_end[];
extern unsigned char _end[];
#ifdef LOADER_FDT_SUPPORT
extern int command_fdt_internal(int argc, char *argv[]);
#endif
static void
dump_sig(struct api_signature *sig)
{
@ -271,3 +275,20 @@ command_sysinfo(int argc, char *argv[])
ub_dump_si(si);
return (CMD_OK);
}
#ifdef LOADER_FDT_SUPPORT
/*
* Since proper fdt command handling function is defined in fdt_loader_cmd.c,
* and declaring it as extern is in contradiction with COMMAND_SET() macro
* (which uses static pointer), we're defining wrapper function, which
* calls the proper fdt handling routine.
*/
static int
command_fdt(int argc, char *argv[])
{
return (command_fdt_internal(argc, argv));
}
COMMAND_SET(fdt, "fdt", "flattened device tree handling", command_fdt);
#endif

View File

@ -42,6 +42,10 @@ __FBSDID("$FreeBSD$");
#include "bootstrap.h"
#include "glue.h"
#if defined(LOADER_FDT_SUPPORT)
extern int fdt_fixup(void);
#endif
/*
* Return a 'boothowto' value corresponding to the kernel arguments in
* (kargs) and any relevant environment variables.
@ -253,6 +257,7 @@ md_copymodules(vm_offset_t addr)
return(addr);
}
#if !defined(LOADER_FDT_SUPPORT)
/*
* Prepare the bootinfo structure. Put a ptr to the allocated struct in addr,
* return size.
@ -358,9 +363,10 @@ md_bootinfo(struct bootinfo **addr)
return (size);
}
#endif
/*
* Load the information expected by a powerpc kernel.
* Load the information expected by a kernel.
*
* - The 'boothowto' argument is constructed
* - The 'bootdev' argument is constructed
@ -370,7 +376,7 @@ md_bootinfo(struct bootinfo **addr)
int
md_load(char *args, vm_offset_t *modulep)
{
struct preloaded_file *kfp;
struct preloaded_file *kfp, *bfp;
struct preloaded_file *xp;
struct file_metadata *md;
struct bootinfo *bip;
@ -379,6 +385,7 @@ md_load(char *args, vm_offset_t *modulep)
vm_offset_t envp;
vm_offset_t size;
vm_offset_t vaddr;
vm_offset_t dtbp;
char *rootdevname;
int howto;
int bisize;
@ -389,7 +396,11 @@ md_load(char *args, vm_offset_t *modulep)
* relocation.
*/
uint32_t mdt[] = {
MODINFOMD_SSYM, MODINFOMD_ESYM, MODINFOMD_KERNEND, MODINFOMD_ENVP
MODINFOMD_SSYM, MODINFOMD_ESYM, MODINFOMD_KERNEND,
MODINFOMD_ENVP,
#if defined(LOADER_FDT_SUPPORT)
MODINFOMD_DTBP
#endif
};
howto = md_getboothowto(args);
@ -405,24 +416,26 @@ md_load(char *args, vm_offset_t *modulep)
/* Try reading the /etc/fstab file to select the root device */
getrootmount(rootdevname);
/* find the last module in the chain */
/* Find the last module in the chain */
addr = 0;
for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
if (addr < (xp->f_addr + xp->f_size))
addr = xp->f_addr + xp->f_size;
}
/* pad to a page boundary */
/* Pad to a page boundary */
addr = roundup(addr, PAGE_SIZE);
/* copy our environment */
/* Copy our environment */
envp = addr;
addr = md_copyenv(addr);
/* pad to a page boundary */
/* Pad to a page boundary */
addr = roundup(addr, PAGE_SIZE);
#if !defined(LOADER_FDT_SUPPORT)
/* prepare bootinfo */
bisize = md_bootinfo(&bip);
#endif
kernend = 0;
kfp = file_findfile(NULL, "elf32 kernel");
@ -431,14 +444,29 @@ md_load(char *args, vm_offset_t *modulep)
if (kfp == NULL)
panic("can't find kernel file");
file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto);
file_addmetadata(kfp, MODINFOMD_BOOTINFO, bisize, bip);
file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp);
#if defined(LOADER_FDT_SUPPORT)
/* Handle device tree blob */
fdt_fixup();
if ((bfp = file_findfile(NULL, "dtb")) == NULL &&
(howto & RB_VERBOSE))
printf("**WARNING** Booting with no DTB loaded!\n");
dtbp = bfp == NULL ? 0 : bfp->f_addr;
file_addmetadata(kfp, MODINFOMD_DTBP, sizeof dtbp, &dtbp);
#else
file_addmetadata(kfp, MODINFOMD_BOOTINFO, bisize, bip);
#endif
file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
/* Figure out the size and location of the metadata */
*modulep = addr;
size = md_copymodules(0);
kernend = roundup(addr + size, PAGE_SIZE);
/* Provide MODINFOMD_KERNEND */
md = file_findmetadata(kfp, MODINFOMD_KERNEND);
bcopy(&kernend, md->md_data, sizeof kernend);
@ -453,7 +481,9 @@ md_load(char *args, vm_offset_t *modulep)
bcopy(&vaddr, md->md_data, sizeof vaddr);
}
}
/* Only now copy actual modules and metadata */
(void)md_copymodules(addr);
return(0);
return (0);
}

View File

@ -10,6 +10,10 @@ SRCS= devicename.c elf_freebsd.c console.c copy.c disk.c \
CFLAGS+= -ffreestanding -msoft-float
CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/
# Pick up FDT includes
CFLAGS+= -I${.CURDIR}/../../../../sys/contrib/libfdt/
# Pick up the bootstrap header for some interface items
CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../../.. -I.

View File

@ -33,5 +33,6 @@
#define MODINFOMD_HOWTO 0x1002
#define MODINFOMD_KERNEND 0x1003
#define MODINFOMD_BOOTINFO 0x1004
#define MODINFOMD_DTBP 0x1005
#endif /* !_MACHINE_METADATA_H_ */