#! /bin/bash
|
set -e
|
|
unset CDPATH
|
|
# At all time, this variable must be set to either:
|
# "y" if the changes to the Linux tree are specific to the kernel version;
|
# "n" otherwise.
|
patch_kernelversion_specific="n"
|
|
# At all time, this variable must be set to either:
|
# "y" if the changes to the Linux tree are specific to the architecture;
|
# "n" otherwise.
|
patch_architecture_specific="n"
|
|
# At all time, this variable must be set to either:
|
# "y": ignore kernel-version-specific changes;
|
# "n": ignore non-kernel-version-specific changes;
|
# "b": don't filter according to the kernel version.
|
patch_kernelversion_filter="b"
|
|
# At all time, this variable must be set to either:
|
# "y": ignore architecture-specific changes;
|
# "n": ignore non-architecture-specific changes;
|
# "b": don't filter according to the architecture.
|
patch_architecture_filter="b"
|
|
# Default path to kernel tree
|
linux_tree=.
|
|
patch_copytempfile() {
|
file="$1"
|
if ! test -f "$temp_tree/$file"; then
|
subdir=`dirname "$file"`
|
mkdir -p "$temp_tree/$subdir"
|
cp "$linux_tree/$file" "$temp_tree/$file"
|
fi
|
}
|
|
check_filter() {
|
if test "$patch_kernelversion_specific" != "$patch_kernelversion_filter" \
|
-a "$patch_architecture_specific" != "$patch_architecture_filter"; then
|
echo ok
|
elif test -e "$temp_tree/$1"; then
|
echo "$me: inconsistent multiple changes to $1 in Linux kernel tree" >&2
|
echo error
|
else
|
echo ignore
|
fi
|
}
|
|
patch_append() {
|
file="$1"
|
if test "x$output_patch" = "x"; then
|
if test -L "$linux_tree/$file" ; then
|
mv "$linux_tree/$file" "$linux_tree/$file.orig"
|
cp "$linux_tree/$file.orig" "$linux_tree/$file"
|
fi
|
chmod +w "$linux_tree/$file"
|
cat >> "$linux_tree/$file"
|
else
|
if test `check_filter $file` = "ok"; then
|
patch_copytempfile "$file"
|
cat >> "$temp_tree/$file"
|
fi
|
fi
|
}
|
|
patch_ed() {
|
file="$1"
|
if test "x$output_patch" = "x"; then
|
ed -s "$linux_tree/$file" > /dev/null
|
else
|
if test `check_filter $file` = "ok"; then
|
patch_copytempfile "$file"
|
ed -s "$temp_tree/$file" > /dev/null
|
fi
|
fi
|
}
|
|
patch_link() {
|
recursive="$1" # "r" or "n"
|
link_file="$2" # "m", "n" or some file (basename) from $target_dir
|
target_dir="$3"
|
link_dir="$4"
|
|
(
|
if test \! \( x$link_file = xm -o x$link_file = xn \); then
|
find_clean_opt="-name $link_file"
|
find_link_opt=$find_clean_opt
|
else
|
link_makefiles_opt=""
|
if test x$link_file = xm; then
|
link_makefiles_opt="-name Makefile -o"
|
fi
|
if test x$recursive = xr; then
|
recursive_opts="-mindepth 1"
|
dir_opt="-type d -o"
|
else
|
recursive_opt="-maxdepth 1"
|
dir_opt=""
|
fi
|
find_clean_opt="$recursive_opt \( $dir_opt $link_makefiles_opt -name Kconfig -o -name '*.[chS]' -o -name '*.sh' \)"
|
find_link_opt="$recursive_opt \( $link_makefiles_opt -name Kconfig -o -name '*.[chS]' -o -name '*.sh' \)"
|
fi
|
|
if test "x$output_patch" = "x" -a -e $linux_tree/$link_dir; then
|
cd $linux_tree/$link_dir &&
|
eval find . $find_clean_opt |
|
while read f; do
|
if test -L $f -a ! -e $xenomai_root/$target_dir/$f; then rm -Rf $f; fi
|
done
|
fi
|
|
cd $xenomai_root/$target_dir &&
|
eval find . $find_link_opt |
|
while read f; do
|
f=`echo $f | cut -d/ -f2-`
|
d=`dirname $f`
|
if test "x$output_patch" = "x"; then
|
mkdir -p $linux_tree/$link_dir/$d
|
if test x$forcelink = x1 -o \
|
! $xenomai_root/$target_dir/$f -ef $linux_tree/$link_dir/$f;
|
then
|
ln -sf $xenomai_root/$target_dir/$f $linux_tree/$link_dir/$f
|
fi
|
else
|
if test `check_filter $link_dir/$f` = "ok"; then
|
mkdir -p $temp_tree/$link_dir/$d
|
cp $xenomai_root/$target_dir/$f $temp_tree/$link_dir/$f
|
fi
|
fi
|
done
|
)
|
}
|
|
generate_patch() {
|
(
|
cd "$temp_tree"
|
find . -type f |
|
while read f; do
|
diff -Naurd "$linux_tree/$f" "$f" |
|
sed -e "s,^--- ${linux_tree}/\.\(/.*\)$,--- linux\1," \
|
-e "s,^+++ \.\(/.*\)$,+++ linux-patched\1,"
|
done
|
)
|
}
|
|
|
usage='usage: prepare-kernel --linux=<linux-tree> [--dovetail=<dovetail-patch>]|[--ipipe=<ipipe-patch>] [--arch=<arch>] [--outpatch=<file> [--filterkvers=y|n] [--filterarch=y|n]] [--forcelink] [--default] [--verbose]'
|
me=`basename $0`
|
|
while test $# -gt 0; do
|
case "$1" in
|
--linux=*)
|
linux_tree=`echo $1|sed -e 's,^--linux=\\(.*\\)$,\\1,g'`
|
linux_tree=`eval "echo $linux_tree"`
|
;;
|
--adeos=*)
|
pipeline_patch=`echo $1|sed -e 's,^--adeos=\\(.*\\)$,\\1,g'`
|
pipeline_patch=`eval "echo $pipeline_patch"`
|
probe_header=include/linux/ipipe.h
|
arch_probe_header=include/asm/ipipe.h
|
pipeline_type=ipipe
|
;;
|
--ipipe=*)
|
pipeline_patch=`echo $1|sed -e 's,^--ipipe=\\(.*\\)$,\\1,g'`
|
pipeline_patch=`eval "echo $pipeline_patch"`
|
probe_header=include/linux/ipipe.h
|
arch_probe_header=include/asm/ipipe.h
|
pipeline_type=ipipe
|
;;
|
--dovetail=*)
|
pipeline_patch=`echo $1|sed -e 's,^--dovetail=\\(.*\\)$,\\1,g'`
|
pipeline_patch=`eval "echo $pipeline_patch"`
|
probe_header=include/linux/dovetail.h
|
arch_probe_header=include/asm/dovetail.h
|
pipeline_type=dovetail
|
;;
|
--arch=*)
|
linux_arch=`echo $1|sed -e 's,^--arch=\\(.*\\)$,\\1,g'`
|
;;
|
--outpatch=*)
|
output_patch=`echo $1|sed -e 's,^--outpatch=\\(.*\\)$,\\1,g'`
|
;;
|
--filterkvers=*)
|
patch_kernelversion_filter=`echo $1|sed -e 's,^--filterkvers=\\(.*\\)$,\\1,g'`
|
;;
|
--filterarch=*)
|
patch_architecture_filter=`echo $1|sed -e 's,^--filterarch=\\(.*\\)$,\\1,g'`
|
;;
|
--forcelink)
|
forcelink=1
|
;;
|
--default)
|
usedefault=1
|
;;
|
--verbose)
|
verbose=1
|
;;
|
--help)
|
echo "$usage"
|
exit 0
|
;;
|
*)
|
echo "$me: unknown flag: $1" >&2
|
echo "$usage" >&2
|
exit 1
|
;;
|
esac
|
shift
|
done
|
|
# Infere the location of the Xenomai source tree from
|
# the path of the current script.
|
|
script_path=`type -p $0`
|
xenomai_root=`dirname $script_path`/..
|
xenomai_root=`cd $xenomai_root && pwd`
|
|
# Check the Linux tree
|
|
default_linux_tree=/lib/modules/`uname -r`/source
|
|
while test x$linux_tree = x; do
|
if test x$usedefault = x; then
|
echo -n "Linux tree [default $default_linux_tree]: "
|
read linux_tree
|
fi
|
if test x$linux_tree = x; then
|
linux_tree=$default_linux_tree
|
fi
|
if test \! -x "$linux_tree"; then
|
echo "$me: cannot access Linux tree in $linux_tree"
|
linux_tree=
|
usedefault=
|
default_linux_tree=/usr/src
|
else
|
break
|
fi
|
done
|
|
linux_tree=`cd $linux_tree && pwd`
|
linux_out=$linux_tree
|
|
if test \! -r $linux_tree/Makefile; then
|
echo "$me: $linux_tree is not a valid Linux kernel tree" >&2
|
exit 2
|
fi
|
|
# Create an empty output patch file, and initialize the temporary tree.
|
if test "x$output_patch" != "x"; then
|
|
temp_tree=`mktemp -d prepare-kernel-XXX --tmpdir`
|
if [ $? -ne 0 ]; then
|
echo Temporary directory could not be created.
|
exit 1
|
fi
|
|
patchdir=`dirname $output_patch`
|
patchdir=`cd $patchdir && pwd`
|
output_patch=$patchdir/`basename $output_patch`
|
echo > "$output_patch"
|
|
fi
|
|
# Infer the default architecture if unspecified.
|
|
if test x$linux_arch = x; then
|
build_arch=`$xenomai_root/config/config.guess`
|
default_linux_arch=`echo $build_arch|cut -f1 -d-`
|
fi
|
|
while : ; do
|
if test x$linux_arch = x; then
|
if test x$usedefault = x; then
|
echo -n "Target architecture [default $default_linux_arch]: "
|
read linux_arch
|
fi
|
if test "x$linux_arch" = x; then
|
linux_arch=$default_linux_arch
|
fi
|
fi
|
case "$linux_arch" in
|
x86*|i*86|amd*)
|
linux_arch=x86
|
;;
|
powerpc*|ppc*)
|
linux_arch=powerpc
|
;;
|
arm)
|
linux_arch=arm
|
;;
|
arm64|aarch64)
|
linux_arch=arm64
|
;;
|
*)
|
echo "$me: unsupported architecture: $linux_arch" >&2
|
linux_arch=
|
usedefault=
|
;;
|
esac
|
if test \! x$linux_arch = x; then
|
break
|
fi
|
done
|
|
foo=`grep '^KERNELSRC := ' $linux_tree/Makefile | cut -d= -f2`
|
if [ ! -z $foo ] ; then
|
linux_tree=$foo
|
fi
|
unset foo
|
|
eval linux_`grep '^EXTRAVERSION =' $linux_tree/Makefile | sed -e 's, ,,g'`
|
eval linux_`grep '^PATCHLEVEL =' $linux_tree/Makefile | sed -e 's, ,,g'`
|
eval linux_`grep '^SUBLEVEL =' $linux_tree/Makefile | sed -e 's, ,,g'`
|
eval linux_`grep '^VERSION =' $linux_tree/Makefile | sed -e 's, ,,g'`
|
|
linux_version="$linux_VERSION.$linux_PATCHLEVEL.$linux_SUBLEVEL"
|
|
if test x$pipeline_type = x; then
|
if test -r $linux_tree/include/linux/ipipe.h; then
|
probe_header=include/linux/ipipe.h
|
arch_probe_header=include/asm/ipipe.h
|
pipeline_type=ipipe
|
elif test -r $linux_tree/include/linux/dovetail.h; then
|
probe_header=include/linux/dovetail.h
|
arch_probe_header=include/asm/dovetail.h
|
pipeline_type=dovetail
|
fi
|
fi
|
|
if test x$verbose = x1; then
|
echo "Preparing kernel $linux_version$linux_EXTRAVERSION in $linux_tree..."
|
fi
|
|
if test -r $linux_tree/$probe_header; then
|
if test x$verbose = x1; then
|
echo "IRQ pipeline found - bypassing patch."
|
fi
|
else
|
if test x$verbose = x1; then
|
echo "$me: no IRQ pipeline support found." >&2
|
fi
|
while test x$pipeline_patch = x; do
|
echo -n "IRQ pipeline patch: "
|
read pipeline_patch
|
if test \! -r "$pipeline_patch" -o x$pipeline_patch = x; then
|
echo "$me: cannot read IRQ pipeline support from $pipeline_patch" >&2
|
pipeline_patch=
|
fi
|
done
|
patchdir=`dirname $pipeline_patch`;
|
patchdir=`cd $patchdir && pwd`
|
pipeline_patch=$patchdir/`basename $pipeline_patch`
|
curdir=$PWD
|
cd $linux_tree && patch --dry-run -p1 -f < $pipeline_patch || {
|
cd $curdir;
|
echo "$me: Unable to patch kernel $linux_version$linux_EXTRAVERSION with `basename $pipeline_patch`." >&2
|
exit 2;
|
}
|
patch -p1 -f -s < $pipeline_patch
|
cd $curdir
|
fi
|
|
if test \! -r $linux_tree/arch/$linux_arch/$arch_probe_header; then
|
echo "$me: $linux_tree has no IRQ pipeline support for $linux_arch" >&2
|
exit 2
|
fi
|
|
if test x$verbose = x1; then
|
echo "IRQ pipeline installed."
|
fi
|
|
patch_kernelversion_specific="y"
|
|
case $linux_VERSION.$linux_PATCHLEVEL in
|
|
2.*)
|
|
echo "$me: Unsupported kernel version $linux_VERSION.$linux_PATCHLEVEL.x" >&2
|
exit 2
|
;;
|
|
*)
|
|
patch_architecture_specific="y"
|
|
if ! grep -q XENOMAI $linux_tree/init/Kconfig; then
|
version_stamp=`cat $xenomai_root/config/version-code`
|
version_major=`expr $version_stamp : '\([[0-9]]*\)' || true`
|
version_minor=`expr $version_stamp : '[[0-9]]*\.\([[0-9]*]*\)' || true`
|
revision_level=`expr $version_stamp : '[[0-9]]*\.[[0-9]*]*\.\([[0-9]*]*\)' || true`
|
if [ -z "$revision_level" ]; then
|
revision_level=0
|
fi
|
version_string=`cat $xenomai_root/config/version-label`
|
sed -e "s,@VERSION_MAJOR@,$version_major,g" \
|
-e "s,@VERSION_MINOR@,$version_minor,g" \
|
-e "s,@REVISION_LEVEL@,$revision_level,g" \
|
-e "s,@VERSION_STRING@,$version_string,g" \
|
-e "s,@SRCARCH@,$linux_arch,g" \
|
$xenomai_root/scripts/Kconfig.frag |
|
patch_append init/Kconfig
|
fi
|
|
test "x$CONFIG_XENO_REVISION_LEVEL" = "x" && CONFIG_XENO_REVISION_LEVEL=0
|
|
if ! grep -q CONFIG_XENOMAI $linux_tree/arch/$linux_arch/Makefile; then
|
p="KBUILD_CFLAGS += -I\$(srctree)/arch/\$(SRCARCH)/xenomai/include -I\$(srctree)/arch/\$(SRCARCH)/xenomai/$pipeline_type/include -I\$(srctree)/include/xenomai"
|
(echo; echo $p) | patch_append arch/$linux_arch/Makefile
|
p="core-\$(CONFIG_XENOMAI) += arch/$linux_arch/xenomai/$pipeline_type/"
|
echo $p | patch_append arch/$linux_arch/Makefile
|
fi
|
|
patch_architecture_specific="n"
|
|
if ! grep -q CONFIG_XENOMAI $linux_tree/drivers/Makefile; then
|
p="obj-\$(CONFIG_XENOMAI) += xenomai/"
|
( echo ; echo $p ) | patch_append drivers/Makefile
|
fi
|
|
if ! grep -q CONFIG_XENOMAI $linux_tree/kernel/Makefile; then
|
p="obj-\$(CONFIG_XENOMAI) += xenomai/"
|
( echo ; echo $p ) | patch_append kernel/Makefile
|
fi
|
;;
|
|
esac
|
|
# Create local directories then symlink to the source files from
|
# there, so that we don't pollute the Xenomai source tree with
|
# compilation files.
|
|
patch_kernelversion_specific="n"
|
patch_architecture_specific="y"
|
patch_link r m kernel/cobalt/arch/$linux_arch arch/$linux_arch/xenomai
|
patch_link n n kernel/cobalt/include/$pipeline_type arch/$linux_arch/include/$pipeline_type
|
patch_architecture_specific="n"
|
patch_link n m kernel/cobalt kernel/xenomai
|
patch_link n cobalt-core.h kernel/cobalt/trace include/trace/events
|
patch_link n cobalt-rtdm.h kernel/cobalt/trace include/trace/events
|
patch_link n cobalt-posix.h kernel/cobalt/trace include/trace/events
|
patch_link r n kernel/cobalt/include/asm-generic/xenomai include/asm-generic/xenomai
|
patch_link r n kernel/cobalt/include/linux/xenomai include/linux/xenomai
|
patch_link n m kernel/cobalt/posix kernel/xenomai/posix
|
patch_link n m kernel/cobalt/rtdm kernel/xenomai/rtdm
|
patch_link n m kernel/cobalt/$pipeline_type kernel/xenomai/pipeline
|
patch_link r m kernel/drivers drivers/xenomai
|
patch_link n n include/cobalt/kernel include/xenomai/cobalt/kernel
|
patch_link r n include/cobalt/kernel/rtdm include/xenomai/rtdm
|
patch_link r n include/cobalt/kernel/$pipeline_type/pipeline include/xenomai/pipeline
|
patch_link r n include/cobalt/uapi include/xenomai/cobalt/uapi
|
patch_link r n include/rtdm/uapi include/xenomai/rtdm/uapi
|
patch_link n version.h include/xenomai include/xenomai
|
patch_link n stdarg.h kernel/cobalt/include/linux include/xenomai/linux
|
|
if test "x$output_patch" != "x"; then
|
if test x$verbose = x1; then
|
echo 'Generating patch.'
|
fi
|
generate_patch > "$output_patch"
|
rm -rf $temp_tree
|
fi
|
|
if test x$verbose = x1; then
|
echo 'Links installed.'
|
echo 'Build system ready.'
|
fi
|
|
exit 0
|