Fix MFS builds when both MD_ROOT_SIZE and MFS_IMAGE are specified

MD_ROOT_SIZE and embed_mfs.sh were basically retired as part of
https://reviews.freebsd.org/D2903 .
However, when building a kernel with 'options MD_ROOT_SIZE' specified, this
results in a non-working MFS, as within sys/dev/md/md.c we fall within the
wrong # ifdef.

This patch implements the following:

* Allow kernels to be built without the MD_ROOT_SIZE option, which results
  in a kernel built as per D2903.
* Allow kernels to be built with the MD_ROOT_SIZE option, which results
  in a kernel built similarly to the pre-D2903 way, with the following
  differences:
  * The MFS is now put in a separate section within the kernel (oldmfs,
    so it differs from the mfs section introduced by D2903).
  * embed_mfs.sh is changed, so it looks up the oldmfs section within the
    kernel, gets its size and offset, sees if the MFS will fit within the
    allocated oldmfs section and only if all is well does a dd of the MFS
    image into the kernel.

Submitted by:	Stanislav Galabov <sgalabov@gmail.com>
Reviewed by:	brooks, imp
Differential Revision:	https://reviews.freebsd.org/D5093
This commit is contained in:
Adrian Chadd 2016-02-02 07:02:51 +00:00
parent 7325dfbb59
commit f4c1f0b9eb
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=295137
5 changed files with 40 additions and 15 deletions

View File

@ -1078,6 +1078,14 @@ options UFS_GJOURNAL
# Make space in the kernel for a root filesystem on a md device. # Make space in the kernel for a root filesystem on a md device.
# Define to the number of kilobytes to reserve for the filesystem. # Define to the number of kilobytes to reserve for the filesystem.
# This is now optional.
# If not defined, the root filesystem passed in as the MFS_IMAGE makeoption
# will be automatically embedded in the kernel during linking. Its exact size
# will be consumed within the kernel.
# If defined, the old way of embedding the filesystem in the kernel will be
# used. That is to say MD_ROOT_SIZE KB will be allocated in the kernel and
# later, the filesystem image passed in as the MFS_IMAGE makeoption will be
# dd'd into the reserved space if it fits.
options MD_ROOT_SIZE=10 options MD_ROOT_SIZE=10
# Make the md device a potential root device, either with preloaded # Make the md device a potential root device, either with preloaded

View File

@ -130,6 +130,9 @@ ${FULLKERNEL}: ${SYSTEM_DEP} vers.o
@rm -f ${.TARGET} @rm -f ${.TARGET}
@echo linking ${.TARGET} @echo linking ${.TARGET}
${SYSTEM_LD} ${SYSTEM_LD}
.if !empty(MD_ROOT_SIZE_CONFIGURED) && defined(MFS_IMAGE)
@sh ${S}/tools/embed_mfs.sh ${.TARGET} ${MFS_IMAGE}
.endif
.if ${MK_CTF} != "no" .if ${MK_CTF} != "no"
@echo ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ... @echo ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ...
@${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${SYSTEM_OBJS} vers.o @${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${SYSTEM_OBJS} vers.o
@ -353,6 +356,7 @@ vnode_if_typedef.h:
${AWK} -f $S/tools/vnode_if.awk $S/kern/vnode_if.src -q ${AWK} -f $S/tools/vnode_if.awk $S/kern/vnode_if.src -q
.if ${MFS_IMAGE:Uno} != "no" .if ${MFS_IMAGE:Uno} != "no"
.if empty(MD_ROOT_SIZE_CONFIGURED)
# Generate an object file from the file system image to embed in the kernel # 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 # 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, # start/end/size variables to __start_mfs, __stop_mfs, and mfs_size,
@ -372,6 +376,7 @@ embedfs_${MFS_IMAGE:T:R}.o: ${MFS_IMAGE}
_binary_${MFS_IMAGE:C,[^[:alnum:]],_,g}_end=mfs_root_end \ _binary_${MFS_IMAGE:C,[^[:alnum:]],_,g}_end=mfs_root_end \
${.TARGET} ${.TARGET}
.endif .endif
.endif
# XXX strictly, everything depends on Makefile because changes to ${PROF} # XXX strictly, everything depends on Makefile because changes to ${PROF}
# only appear there, but we don't handle that. # only appear there, but we don't handle that.

View File

@ -195,9 +195,13 @@ SYSTEM_DEP= Makefile ${SYSTEM_OBJS}
SYSTEM_OBJS= locore.o ${MDOBJS} ${OBJS} SYSTEM_OBJS= locore.o ${MDOBJS} ${OBJS}
SYSTEM_OBJS+= ${SYSTEM_CFILES:.c=.o} SYSTEM_OBJS+= ${SYSTEM_CFILES:.c=.o}
SYSTEM_OBJS+= hack.So SYSTEM_OBJS+= hack.So
MD_ROOT_SIZE_CONFIGURED!= grep MD_ROOT_SIZE opt_md.h || true ; echo
.if ${MFS_IMAGE:Uno} != "no" .if ${MFS_IMAGE:Uno} != "no"
.if empty(MD_ROOT_SIZE_CONFIGURED)
SYSTEM_OBJS+= embedfs_${MFS_IMAGE:T:R}.o SYSTEM_OBJS+= embedfs_${MFS_IMAGE:T:R}.o
.endif .endif
.endif
SYSTEM_LD= @${LD} -Bdynamic -T ${LDSCRIPT} ${_LDFLAGS} --no-warn-mismatch \ SYSTEM_LD= @${LD} -Bdynamic -T ${LDSCRIPT} ${_LDFLAGS} --no-warn-mismatch \
--warn-common --export-dynamic --dynamic-linker /red/herring \ --warn-common --export-dynamic --dynamic-linker /red/herring \
-o ${.TARGET} -X ${SYSTEM_OBJS} vers.o -o ${.TARGET} -X ${SYSTEM_OBJS} vers.o
@ -230,8 +234,9 @@ MKMODULESENV+= __MPATH="${__MPATH}"
# Architecture and output format arguments for objdump to convert image to # Architecture and output format arguments for objdump to convert image to
# object file # object file
.if ${MFS_IMAGE:Uno} != "no"
.if ${MFS_IMAGE:Uno} != "no"
.if empty(MD_ROOT_SIZE_CONFIGURED)
.if !defined(EMBEDFS_FORMAT.${MACHINE_ARCH}) .if !defined(EMBEDFS_FORMAT.${MACHINE_ARCH})
EMBEDFS_FORMAT.${MACHINE_ARCH}!= awk -F'"' '/OUTPUT_FORMAT/ {print $$2}' ${LDSCRIPT} EMBEDFS_FORMAT.${MACHINE_ARCH}!= awk -F'"' '/OUTPUT_FORMAT/ {print $$2}' ${LDSCRIPT}
.if empty(EMBEDFS_FORMAT.${MACHINE_ARCH}) .if empty(EMBEDFS_FORMAT.${MACHINE_ARCH})
@ -254,6 +259,7 @@ EMBEDFS_FORMAT.mips64?= elf64-tradbigmips
EMBEDFS_FORMAT.mips64el?= elf64-tradlittlemips EMBEDFS_FORMAT.mips64el?= elf64-tradlittlemips
EMBEDFS_FORMAT.riscv?= elf64-littleriscv EMBEDFS_FORMAT.riscv?= elf64-littleriscv
.endif .endif
.endif
# Detect kernel config options that force stack frames to be turned on. # Detect kernel config options that force stack frames to be turned on.
DDB_ENABLED!= grep DDB opt_ddb.h || true ; echo DDB_ENABLED!= grep DDB opt_ddb.h || true ; echo

View File

@ -130,18 +130,12 @@ SYSCTL_INT(_vm, OID_AUTO, md_malloc_wait, CTLFLAG_RW, &md_malloc_wait, 0,
*/ */
#if defined(MD_ROOT_SIZE) #if defined(MD_ROOT_SIZE)
/* /*
* We put the mfs_root symbol into the oldmfs section of the kernel object file.
* Applications that patch the object with the image can determine * Applications that patch the object with the image can determine
* the size looking at the start and end markers (strings), * the size looking at the oldmfs section size within the kernel.
* so we want them contiguous.
*/ */
static struct { u_char mfs_root[MD_ROOT_SIZE*1024] __attribute__ ((section ("oldmfs")));
u_char start[MD_ROOT_SIZE*1024]; const int mfs_root_size = sizeof(mfs_root);
u_char end[128];
} mfs_root = {
.start = "MFS Filesystem goes here",
.end = "MFS Filesystem had better STOP here",
};
const int mfs_root_size = sizeof(mfs_root.start);
#else #else
extern volatile u_char __weak_symbol mfs_root; extern volatile u_char __weak_symbol mfs_root;
extern volatile u_char __weak_symbol mfs_root_end; extern volatile u_char __weak_symbol mfs_root_end;

View File

@ -32,8 +32,20 @@
# $2: MFS image filename # $2: MFS image filename
# #
obs=`strings -at d $1 | grep "MFS Filesystem goes here" | awk '{print $1}'` mfs_size=`stat -f '%z' $2 2> /dev/null`
dd if=$2 ibs=8192 of=$1 obs=${obs} oseek=1 conv=notrunc 2> /dev/null # If we can't determine MFS image size - bail.
[ -z ${mfs_size} ] && echo "Can't determine MFS image size" && exit 1
strings $1 | grep 'MFS Filesystem had better STOP here' > /dev/null || \ sec_info=`objdump -h $1 2> /dev/null | grep " oldmfs "`
(rm $1 && echo "MFS image too large" && false) # If we can't find the mfs section within the given kernel - bail.
[ -z "${sec_info}" ] && echo "Can't locate mfs section within kernel" && exit 1
sec_size=`echo ${sec_info} | awk '{printf("%d", "0x" $3)}' 2> /dev/null`
sec_start=`echo ${sec_info} | awk '{printf("%d", "0x" $6)}' 2> /dev/null`
# If the mfs section size is smaller than the mfs image - bail.
[ ${sec_size} -lt ${mfs_size} ] && echo "MFS image too large" && exit 1
# Dump the mfs image into the mfs section
dd if=$2 ibs=8192 of=$1 obs=${sec_start} oseek=1 conv=notrunc 2> /dev/null && \
echo "MFS image embedded into kernel" && exit 0