加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

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#
==============================================
一开始以为内核模块编译用到的头文件是在编译内核是可以选择生成的,结果发现不一样,找了一个脚本,勉强可以生成,但还有些错误没有订正,有空再研究
==========================
#!/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/

        # let's make sure that objtool compilation won't overwrite the native fixdep we just copied so we rename it to fixdep_temp
        sed -i 's|$(QUIET_LINK)$(HOSTCC) $(LDFLAGS) -o $@ $<|$(QUIET_LINK)$(HOSTCC) $(LDFLAGS) -o fixdep_temp $<|' tools/build/Makefile

        # trying to apply the previous sed in context of 4.18 kernel
        sed -i 's|$(QUIET_LINK)$(HOSTCC) $(HOSTLDFLAGS) -o $@ $<|$(QUIET_LINK)$(HOSTCC) $(HOSTLDFLAGS) -o fixdep_temp $<|' tools/build/Makefile
        # trying to apply the previous sed in context of 5.0.3 kernel
        sed -i 's|$(QUIET_LINK)$(HOSTCC) $(KBUILD_HOSTLDFLAGS) -o $@ $<|$(QUIET_LINK)$(HOSTCC) $(KBUILD_HOSTLDFLAGS) -o fixdep_temp $<|' tools/build/Makefile
        fi

        echo Building objtool for target
        make -C tools/objtool HOSTCC="$hostcc" HOSTLD="$LD" $build_opts
        rm -rf tools/objtool/fixdep tools/objtool/fixdep_temp
        mv .backup.tools.build.Makefile tools/build/Makefile

            if [[ -e tools/build/Makefile ]]; then
            echo Building fixdep for target
            make -C tools/build HOSTCC="$hostcc" HOSTLD="$LD" $build_opts

                # move the target fixdep to the expected location
                mv tools/build/fixdep tools/objtool/
            fi
    fi

    echo Cleaning up directory...

    # Reinstate pristine Makefile's.
    mv .backup.basic.Makefile scripts/basic/Makefile
    mv .backup.kbuild.Makefile.include scripts/Kbuild.include
    mv .backup.Makefile.build scripts/Makefile.build
    mv .backup.mod.Makefile scripts/mod/Makefile
    mv .backup.kconfig.Makefile scripts/kconfig/Makefile

    # Clean up host script bins.
    rm -rf xscripts
    if [ -d xtools ]; then
        rm -rf xtools
    fi

    # Remove unneeded binary and object files
    rm -rf arch/x86/tools/relocs arch/x86/tools/relocs*.o

    pop
fi

echo Done!

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有