Commit 28766fd2 authored by marcel's avatar marcel
Browse files

Change md(4) to use weak symbols as start, end and size for the embedded

root disk. The embedded image is linked into the kernel in the .mfs
section.

Add rules and variables to kern.pre.mk and kern.post.mk that handle the
linking of the image. First objcopy is used to generate an object file.
Then, the object file is linked into the kernel.

Submitted by:	Steve Kiernan <stevek@juniper.net>
Reviewed by:	brooks@
Obtained from: Juniper Networks, Inc.
Differential Revision:	https://reviews.freebsd.org/D2903
parent 370eb0c5
......@@ -66,10 +66,6 @@ SYSTEM_LD_TAIL +=;sed s/" + SIZEOF_HEADERS"// ldscript.$M\
${KERNEL_KO}.bin; \
rm ${FULLKERNEL}.noheader
.if defined(MFS_IMAGE)
SYSTEM_LD_TAIL += ;sh ${S}/tools/embed_mfs.sh ${KERNEL_KO}.bin ${MFS_IMAGE};
.endif
FILES_CPU_FUNC = \
$S/$M/$M/cpufunc_asm_arm9.S \
$S/$M/$M/cpufunc_asm_arm10.S \
......
......@@ -121,7 +121,7 @@ gdbinit:
.endif
.endif
${FULLKERNEL}: ${SYSTEM_DEP} vers.o ${MFS_IMAGE}
${FULLKERNEL}: ${SYSTEM_DEP} vers.o
@rm -f ${.TARGET}
@echo linking ${.TARGET}
${SYSTEM_LD}
......@@ -133,9 +133,6 @@ ${FULLKERNEL}: ${SYSTEM_DEP} vers.o ${MFS_IMAGE}
${OBJCOPY} --strip-debug ${.TARGET}
.endif
${SYSTEM_LD_TAIL}
.if defined(MFS_IMAGE)
sh ${S}/tools/embed_mfs.sh ${FULLKERNEL} ${MFS_IMAGE}
.endif
.if !exists(${.OBJDIR}/.depend)
${SYSTEM_OBJS}: assym.s vnode_if.h ${BEFORE_DEPEND:M*.h} ${MFILES:T:S/.m$/.h/}
......@@ -301,6 +298,27 @@ vnode_if_newproto.h:
vnode_if_typedef.h:
${AWK} -f $S/tools/vnode_if.awk $S/kern/vnode_if.src -q
.if ${MFS_IMAGE:Uno} != "no"
# Generate an object file from the file system image to embed in the kernel
# via linking. Make sure the contents are in the mfs section and rename the
# start/end/size variables to __start_mfs, __stop_mfs, and mfs_size,
# respectively.
embedfs_${MFS_IMAGE:T:R}.o: ${MFS_IMAGE}
${OBJCOPY} --input-target binary \
--output-target ${EMBEDFS_FORMAT.${MACHINE_ARCH}} \
--binary-architecture ${EMBEDFS_ARCH.${MACHINE_ARCH}} \
${MFS_IMAGE} ${.TARGET}
${OBJCOPY} \
--rename-section .data=mfs,contents,alloc,load,readonly,data \
--redefine-sym \
_binary_${MFS_IMAGE:C,[^[:alnum:]],_,g}_size=__mfs_root_size \
--redefine-sym \
_binary_${MFS_IMAGE:C,[^[:alnum:]],_,g}_start=mfs_root \
--redefine-sym \
_binary_${MFS_IMAGE:C,[^[:alnum:]],_,g}_end=mfs_root_end \
${.TARGET}
.endif
# XXX strictly, everything depends on Makefile because changes to ${PROF}
# only appear there, but we don't handle that.
......
......@@ -191,6 +191,9 @@ SYSTEM_DEP= Makefile ${SYSTEM_OBJS}
SYSTEM_OBJS= locore.o ${MDOBJS} ${OBJS}
SYSTEM_OBJS+= ${SYSTEM_CFILES:.c=.o}
SYSTEM_OBJS+= hack.So
.if ${MFS_IMAGE:Uno} != "no"
SYSTEM_OBJS+= embedfs_${MFS_IMAGE:T:R}.o
.endif
SYSTEM_LD= @${LD} -Bdynamic -T ${LDSCRIPT} ${_LDFLAGS} --no-warn-mismatch \
--warn-common --export-dynamic --dynamic-linker /red/herring \
-o ${.TARGET} -X ${SYSTEM_OBJS} vers.o
......@@ -222,6 +225,32 @@ MKMODULESENV+= DEBUG_FLAGS="${DEBUG}"
.endif
MKMODULESENV+= _MPATH="${_MPATH}"
# Architecture and output format arguments for objdump to convert image to
# object file
.if ${MFS_IMAGE:Uno} != "no"
.if !defined(EMBEDFS_FORMAT.${MACHINE_ARCH})
EMBEDFS_FORMAT.${MACHINE_ARCH}!= awk -F'"' '/OUTPUT_FORMAT/ {print $$2}' ${LDSCRIPT}
.if empty(EMBEDFS_FORMAT.${MACHINE_ARCH})
.undef EMBEDFS_FORMAT.${MACHINE_ARCH}
.endif
.endif
.if !defined(EMBEDFS_ARCH.${MACHINE_ARCH})
EMBEDFS_ARCH.${MACHINE_ARCH}!= sed -n '/OUTPUT_ARCH/s/.*(\(.*\)).*/\1/p' ${LDSCRIPT}
.if empty(EMBEDFS_ARCH.${MACHINE_ARCH})
.undef EMBEDFS_ARCH.${MACHINE_ARCH}
.endif
.endif
EMBEDFS_FORMAT.arm?= elf32-littlearm
EMBEDFS_FORMAT.armv6?= elf32-littlearm
EMBEDFS_FORMAT.mips?= elf32-tradbigmips
EMBEDFS_FORMAT.mipsel?= elf32-tradlittlemips
EMBEDFS_FORMAT.mips64?= elf64-tradbigmips
EMBEDFS_FORMAT.mips64el?= elf64-tradlittlemips
.endif
# Detect kernel config options that force stack frames to be turned on.
DDB_ENABLED!= grep DDB opt_ddb.h || true ; echo
DTR_ENABLED!= grep KDTRACE_FRAME opt_kdtrace.h || true ; echo
......
......@@ -122,9 +122,12 @@ SYSCTL_INT(_vm, OID_AUTO, md_malloc_wait, CTLFLAG_RW, &md_malloc_wait, 0,
#define MD_ROOT_FSTYPE "ufs"
#endif
#if defined(MD_ROOT) && defined(MD_ROOT_SIZE)
#if defined(MD_ROOT)
/*
* Preloaded image gets put here.
*/
#if defined(MD_ROOT_SIZE)
/*
* Applications that patch the object with the image can determine
* the size looking at the start and end markers (strings),
* so we want them contiguous.
......@@ -136,6 +139,14 @@ static struct {
.start = "MFS Filesystem goes here",
.end = "MFS Filesystem had better STOP here",
};
const int mfs_root_size = sizeof(mfs_root.start);
#else
extern volatile u_char __weak_symbol mfs_root;
extern volatile u_char __weak_symbol mfs_root_end;
__GLOBL(mfs_root);
__GLOBL(mfs_root_end);
#define mfs_root_size ((uintptr_t)(&mfs_root_end - &mfs_root))
#endif
#endif
static g_init_t g_md_init;
......@@ -1553,6 +1564,9 @@ md_preloaded(u_char *image, size_t length, const char *name)
if (name != NULL) {
printf("%s%d: Preloaded image <%s> %zd bytes at %p\n",
MD_NAME, sc->unit, name, length, image);
} else {
printf("%s%d: Embedded image %zd bytes as %p\n",
MD_NAME, sc->unit, length, image);
}
}
......@@ -1572,10 +1586,13 @@ g_md_init(struct g_class *mp __unused)
sx_init(&md_sx, "MD config lock");
g_topology_unlock();
md_uh = new_unrhdr(0, INT_MAX, NULL);
#ifdef MD_ROOT_SIZE
sx_xlock(&md_sx);
md_preloaded(mfs_root.start, sizeof(mfs_root.start), NULL);
sx_xunlock(&md_sx);
#ifdef MD_ROOT
if (mfs_root_size != 0) {
sx_xlock(&md_sx);
md_preloaded(__DEVOLATILE(u_char *, &mfs_root), mfs_root_size,
NULL);
sx_xunlock(&md_sx);
}
#endif
/* XXX: are preload_* static or do they need Giant ? */
while ((mod = preload_search_next_name(mod)) != NULL) {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment