linux内核模块交叉编译例子
(2020-09-13 07:20:13)
标签:
linux内核模块交叉编译 |
分类: programming |
合作项目的外方说内核模块编译出错,整理了个linux内核模块外部交叉编译例子,中间也编译不过,后来发现是内核编译时的编译选项问题导致一些变量没有输出,需要保证make
menuconfig正确
=====================================================
root@semon-VirtualBox:/home/semon/test/kmodule#
cat Makefile
ifneq ($(KERNELRELEASE),)
obj-m:=ex.o
ex-objs:=exps.o exps.o exp.o
else
#generate the path
CURRENT_PATH:=$(shell pwd)
CONFIG_MODULE_SIG = n
#the absolute path
CROSS_COMPILE=/opt/gcc-4.9.3-64-gnu64/bin/mips64el-linux-
LINUX_KERNEL_PATH:=/opt/linux-3.10/
#complie object
default:
make
ARCH=mips CROSS_COMPILE=$(CROSS_COMPILE) -C $(LINUX_KERNEL_PATH)
M=$(CURRENT_PATH) modules
clean:
make -C
$(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
endif
root@semon-VirtualBox:/home/semon/test/kmodule# ls
ex.ko ex.mod.c
ex.mod.o ex.o
exp.c exp.h
exp.o exps.c
exps.o Makefile
modules.order Module.symvers
root@semon-VirtualBox:/home/semon/test/kmodule# ls -al
total 132
drwxrwxr-x 3 semon semon 4096
9月 13 06:15 .
drwxrwxr-x 25 semon semon 4096
9月 12 19:37 ..
-rw-r--r-- 1 root
root 4692 9月
13 06:15 ex.ko
-rw-r--r-- 1 root
root 244
9月 13 06:15 .ex.ko.cmd
-rw-r--r-- 1 root
root 582
9月 13 06:15 ex.mod.c
-rw-r--r-- 1 root
root 2648 9月
13 06:15 ex.mod.o
-rw-r--r-- 1 root
root 25181 9月 13 06:15
.ex.mod.o.cmd
-rw-r--r-- 1 root
root 3200 9月
13 06:15 ex.o
-rw-r--r-- 1 root
root 201
9月 13 06:15 .ex.o.cmd
-rw-rw-r-- 1 semon
semon 424 9月
12 21:53 exp.c
-rw-rw-r-- 1 semon
semon 91
9月 12 20:10 exp.h
-rw-r--r-- 1 root
root 2512 9月
13 06:15 exp.o
-rw-r--r-- 1 root
root 25124 9月 13 06:15
.exp.o.cmd
-rw-rw-r-- 1 semon
semon 175 9月
12 20:09 exps.c
-rw-r--r-- 1 root
root 2144 9月
13 06:15 exps.o
-rw-r--r-- 1 root
root 7662 9月
13 06:15 .exps.o.cmd
-rw-rw-r-- 1 semon
semon 447 9月
13 06:15 Makefile
-rw-r--r-- 1 root
root
38 9月 13 06:15 modules.order
-rw-r--r-- 1 root
root
0 9月 12 21:49 Module.symvers
drwxr-xr-x 2 root
root 4096 9月
13 06:15 .tmp_versions
root@semon-VirtualBox:/home/semon/test/kmodule#
ifneq ($(KERNELRELEASE),)
obj-m:=ex.o
ex-objs:=exps.o exps.o exp.o
else
#generate the path
CURRENT_PATH:=$(shell pwd)
CONFIG_MODULE_SIG = n
#the absolute path
CROSS_COMPILE=/opt/gcc-4.9.3-64-gnu64/bin/mips64el-linux-
LINUX_KERNEL_PATH:=/opt/linux-3.10/
#complie object
default:
clean:
endif
root@semon-VirtualBox:/home/semon/test/kmodule# ls
ex.ko
root@semon-VirtualBox:/home/semon/test/kmodule# ls -al
total 132
drwxrwxr-x
drwxrwxr-x 25 semon semon
-rw-r--r--
-rw-r--r--
-rw-r--r--
-rw-r--r--
-rw-r--r--
-rw-r--r--
-rw-r--r--
-rw-rw-r--
-rw-rw-r--
-rw-r--r--
-rw-r--r--
-rw-rw-r--
-rw-r--r--
-rw-r--r--
-rw-rw-r--
-rw-r--r--
-rw-r--r--
drwxr-xr-x
root@semon-VirtualBox:/home/semon/test/kmodule#
==============================================
一开始以为内核模块编译用到的头文件是在编译内核是可以选择生成的,结果发现不一样,找了一个脚本,勉强可以生成,但还有些错误没有订正,有空再研究
==========================
#!/bin/bash
set -x
set -e; set -o pipefail
# Heavily based on PKGBUILD from
# https://www.archlinux.org/packages/core/x86_64/linux/
function error()
{
echo
$(basename $0): $@ >&2
}
function fatal()
{
error
$@
exit 1
}
function usage()
{
echo "usage:
$(basename $0) [target dir] [linux source dir] [objects dir]
">&2
exit 1
}
# See http://stackoverflow.com/a/4774063
function get_full_path()
{
echo "$( cd
"$1" ; pwd -P )"
}
function push()
{
pushd $@
>/dev/null
}
function push_linux()
{
push
$linux_dir
}
function pop()
{
popd
>/dev/null
}
function copy_dir()
{
from="$1"
to="$2"
if [[ -d
"$from" ]]; then
cp -a "$from" "$to"
fi
}
function copy_mkdir()
{
local
target_dir="$1"
local
rel_path="$2"
mkdir -p
"$target_dir/$(dirname $rel_path)"
cp
"$rel_path" "$target_dir/$rel_path"
}
[[ $# -ge 3 ]] || usage
# Generate target dir if doesn't exist.
install -dm755 $1
target_dir=$(get_full_path $1)
linux_dir=$(get_full_path $2)
# The directory containing .config and Module.symvers.
obj_dir=$(get_full_path $3)
karch=${4:-x86}
prefix=$5
hostcc="${6:-${prefix}gcc}"
hostcc_native="${7:-${prefix}gcc}"
# FIXME: We assume host arch == x86.
if [[ "$karch" != "x86" ]]; then
[[ -n
$prefix ]] || fatal "Non-x86 arch but no prefix specified."
fi
build_opts=""
# Regardless of target arch, if a prefix is specified we are cross-compiling.
[[ -z "$prefix" ]] || build_opts="ARCH=$karch CROSS_COMPILE=$prefix"
karch_dir="arch/$karch"
target_karch_dir="$target_dir/$karch_dir"
[[ -f "${obj_dir}/.config" ]] || fatal "Missing kernel configuration."
[[ -f "${obj_dir}/Module.symvers" ]] || fatal "Missing Module.symvers."
# Copy in .config and Module.symvers so we can specify O=$target_dir.
cp "${obj_dir}/.config" "${obj_dir}/Module.symvers" "$linux_dir/Makefile.qlock" "$target_dir"
extra_header_dirs="drivers/md net/mac80211 drivers/media/dvb-core include/config/dvb \
drivers/media/dvb-frontends drivers/media/usb/dvb-usb drivers/media/tuners"
push_linux
trap pop EXIT
[[ -d "$karch_dir" ]] || fatal "Unrecognised karch: $karch"
echo Running modules_prepare...
#make HOSTCC="$hostcc_native" O="$target_dir" $build_opts modules_prepare V=1
make $build_opts modules_prepare
echo Copying required files...
if [[ -n "$prefix" ]]; then
# Move host
arch script binaries so we can fix them up later. We don't want
to
# keep host
binaries in place when we copy in source, we'll compile target
arch
# versions
later.
mv
"$target_dir"/scripts "$target_dir"/xscripts
if [ -d
"$target_dir/tools" ]; then
mv "$target_dir"/tools "$target_dir"/xtools
fi
fi
for f in Makefile kernel/Makefile Documentation/DocBook/Makefile; do
# DocBook
support is removed in 4.13
if [ -f "$f"
]; then
install -D -m644 "$f" "$target_dir/$f"
fi
done
# Arch Linux copies only specific directories, however the difference is 31M
# vs. 37M (~168k compressed) so for future-proofing I think it's not much more
# of a cost to just copy everything.
find include -mindepth 1 -maxdepth 1 -type d | \
xargs -I {}
cp -a "{}" "$target_dir/include"
for d in include $extra_header_dirs; do
[ -d "$d" ]
&& mkdir -p "$target_dir/$d"
done
# Configure arch/ directory.
mkdir -p "$target_karch_dir"
copy_dir "$karch_dir/include" "$target_karch_dir"
copy_dir "$karch_dir/tools" "$target_karch_dir"
echo "$karch_dir"
echo "$target_karch_dir"
cp $karch_dir/Kbuild.platforms $target_karch_dir/
for f in $(find $karch_dir -iname '*.h' -o -name 'Makefile' -o -iname '*.tbl' -o -iname '*.sh' -o -iname 'Platform'); do
echo
"$f"
copy_mkdir
"$target_dir" "$f"
done
for f in $(find security -iname '*.h'); do
copy_mkdir
"$target_dir" "$f"
done
# Copy over tools include as some builds require this.
mkdir -p "$target_dir/tools"
copy_dir tools/include "$target_dir/tools"
copy_dir tools/objtool "$target_dir/tools"
copy_dir tools/lib "$target_dir/tools"
copy_dir tools/scripts "$target_dir/tools"
copy_dir tools/build "$target_dir/tools"
cp tools/Makefile "$target_dir/tools"
copy_dir scripts "$target_dir"
# Don't strip binaries as only makes 200kb difference...
mkdir -p "$target_karch_dir/kernel"
cp "$karch_dir/Makefile" "$target_karch_dir"
# May as well always copy these if available.
for f in Makefile_32.cpu kernel/asm-offsets.s; do
p="$karch_dir/$f"
[ -f $p ]
&& cp "$p" "$target_karch_dir/$f"
done
# Address sources with this kind of hacks
# https://github.com/raspberrypi/linux/commit/a66649dab35033bd67988670fa60c268b0444cda
mkdir -p "$target_karch_dir/kernel/vdso"
for f in gettimeofday.S note.S sigreturn.S; do
p="$karch_dir//kernel/vdso/$f"
[ -f $p ]
&& cp "$p" "$target_karch_dir/kernel/vdso/$f"
done
# Copy in extra headers. Directories already created above.
for d in $extra_header_dirs; do
[ -d "$d" ]
&& (cp $d/*.h "$target_dir/$d" || true)
done
# Specific required files.
if [[ -e drivers/media/i2c/msp3400-driver.h ]]; then
mkdir -p
"$target_dir/drivers/media/i2c/"
cp
drivers/media/i2c/msp3400-driver.h
"$target_dir/drivers/media/i2c/"
fi
# Copy in Kconfig files.
for f in $(find . -name "Kconfig*"); do
copy_mkdir
"$target_dir" "$f"
done
# Fix arm64 file reference
if [ "$karch" = "arm64" ] && [ -f "$karch_dir/include/asm/opcodes.h" ]; then
copy_mkdir
"$target_dir" "./arch/arm/include/asm/opcodes.h"
fi
# copy module.lds if it exists
if [ "$karch" = "arm64" ] && [ -f "arch/arm64/kernel/module.lds" ]; then
copy_mkdir
"$target_dir" "./arch/arm64/kernel/module.lds"
fi
if [[ -n "$prefix" ]]; then
echo Fixing
up script binaries...
push
"$target_dir"
# Make some
backups so we can restore sanity after we're done.
cp
scripts/basic/Makefile .backup.basic.Makefile
cp
scripts/Kbuild.include .backup.kbuild.Makefile.include
cp
scripts/Makefile.build .backup.Makefile.build
cp
scripts/mod/Makefile .backup.mod.Makefile
cp
scripts/kconfig/Makefile .backup.kconfig.Makefile
if [[ -e
tools/build/Makefile ]]; then
cp tools/build/Makefile .backup.tools.build.Makefile
fi
# Fixup
Makefile's so they reference our host arch binaries in
xscripts.
# We only
need a few fixups since we're only building scripts here.
sed -i
's|$(obj)/fixdep|x$(obj)/fixdep|' scripts/basic/Makefile
sed -i
's|scripts/basic/fixdep|xscripts/basic/fixdep|'
scripts/Kbuild.include
sed -i
's|scripts/basic/fixdep|xscripts/basic/fixdep|'
scripts/Makefile.build
sed -i
's|$(obj)/mk_elfconfig|x$(obj)/mk_elfconfig|'
scripts/mod/Makefile
sed -i
's|$(obj)/conf|x$(obj)/conf|' scripts/kconfig/Makefile
echo
Building script binaries for target arch...
# make
HOSTCC="$hostcc" HOSTLD="$LD" $build_opts scripts
make
HOSTLD="$LD" $build_opts scripts
echo
"test0"
# for kernel
5.0.3 the following also builds scripts/mod which was removed from
"make scripts" (see
https://patchwork.kernel.org/patch/10690901/)
make
HOSTCC="$hostcc" HOSTLD="$LD" $build_opts prepare0
if [[ -e
xtools/objtool/fixdep ]]; then
if [[ -e tools/build/Makefile ]]; then
# let's use the native fixdep for the target objtool
compilation
cp xtools/objtool/fixdep tools/objtool/
set -x
set -e; set -o pipefail
# Heavily based on PKGBUILD from
# https://www.archlinux.org/packages/core/x86_64/linux/
function error()
{
}
function fatal()
{
}
function usage()
{
}
# See http://stackoverflow.com/a/4774063
function get_full_path()
{
}
function push()
{
}
function push_linux()
{
}
function pop()
{
}
function copy_dir()
{
}
function copy_mkdir()
{
}
[[ $# -ge 3 ]] || usage
# Generate target dir if doesn't exist.
install -dm755 $1
target_dir=$(get_full_path $1)
linux_dir=$(get_full_path $2)
# The directory containing .config and Module.symvers.
obj_dir=$(get_full_path $3)
karch=${4:-x86}
prefix=$5
hostcc="${6:-${prefix}gcc}"
hostcc_native="${7:-${prefix}gcc}"
# FIXME: We assume host arch == x86.
if [[ "$karch" != "x86" ]]; then
fi
build_opts=""
# Regardless of target arch, if a prefix is specified we are cross-compiling.
[[ -z "$prefix" ]] || build_opts="ARCH=$karch CROSS_COMPILE=$prefix"
karch_dir="arch/$karch"
target_karch_dir="$target_dir/$karch_dir"
[[ -f "${obj_dir}/.config" ]] || fatal "Missing kernel configuration."
[[ -f "${obj_dir}/Module.symvers" ]] || fatal "Missing Module.symvers."
# Copy in .config and Module.symvers so we can specify O=$target_dir.
cp "${obj_dir}/.config" "${obj_dir}/Module.symvers" "$linux_dir/Makefile.qlock" "$target_dir"
extra_header_dirs="drivers/md net/mac80211 drivers/media/dvb-core include/config/dvb \
drivers/media/dvb-frontends drivers/media/usb/dvb-usb drivers/media/tuners"
push_linux
trap pop EXIT
[[ -d "$karch_dir" ]] || fatal "Unrecognised karch: $karch"
echo Running modules_prepare...
#make HOSTCC="$hostcc_native" O="$target_dir" $build_opts modules_prepare V=1
make $build_opts modules_prepare
echo Copying required files...
if [[ -n "$prefix" ]]; then
fi
for f in Makefile kernel/Makefile Documentation/DocBook/Makefile; do
done
# Arch Linux copies only specific directories, however the difference is 31M
# vs. 37M (~168k compressed) so for future-proofing I think it's not much more
# of a cost to just copy everything.
find include -mindepth 1 -maxdepth 1 -type d | \
for d in include $extra_header_dirs; do
done
# Configure arch/ directory.
mkdir -p "$target_karch_dir"
copy_dir "$karch_dir/include" "$target_karch_dir"
copy_dir "$karch_dir/tools" "$target_karch_dir"
echo "$karch_dir"
echo "$target_karch_dir"
cp $karch_dir/Kbuild.platforms $target_karch_dir/
for f in $(find $karch_dir -iname '*.h' -o -name 'Makefile' -o -iname '*.tbl' -o -iname '*.sh' -o -iname 'Platform'); do
done
for f in $(find security -iname '*.h'); do
done
# Copy over tools include as some builds require this.
mkdir -p "$target_dir/tools"
copy_dir tools/include "$target_dir/tools"
copy_dir tools/objtool "$target_dir/tools"
copy_dir tools/lib "$target_dir/tools"
copy_dir tools/scripts "$target_dir/tools"
copy_dir tools/build "$target_dir/tools"
cp tools/Makefile "$target_dir/tools"
copy_dir scripts "$target_dir"
# Don't strip binaries as only makes 200kb difference...
mkdir -p "$target_karch_dir/kernel"
cp "$karch_dir/Makefile" "$target_karch_dir"
# May as well always copy these if available.
for f in Makefile_32.cpu kernel/asm-offsets.s; do
done
# Address sources with this kind of hacks
# https://github.com/raspberrypi/linux/commit/a66649dab35033bd67988670
mkdir -p "$target_karch_dir/kernel/vdso"
for f in gettimeofday.S note.S sigreturn.S; do
done
# Copy in extra headers. Directories already created above.
for d in $extra_header_dirs; do
done
# Specific required files.
if [[ -e drivers/media/i2c/msp3400-driver.h ]]; then
fi
# Copy in Kconfig files.
for f in $(find . -name "Kconfig*"); do
done
# Fix arm64 file reference
if [ "$karch" = "arm64" ] && [ -f "$karch_dir/include/asm/opcodes.h" ]; then
fi
# copy module.lds if it exists
if [ "$karch" = "arm64" ] && [ -f "arch/arm64/kernel/module.lds" ]; then
fi
if [[ -n "$prefix" ]]; then
#