如何编写需要内核源头文件的BitBake驱动程序配方?

时间:2016-01-14 15:43:56

标签: linux-kernel header-files yocto bitbake openembedded

简介

我在BitBake配方中有一个do_install任务,我为执行自定义install脚本的驱动程序编写了该任务。该任务失败,因为安装脚本无法在<the image rootfs>/usr/src/kernel中找到内核源头文件。此脚本在生成的OS上运行正常。

发生了什么

这是我食谱的相关部分:

SRC_URI += "file://${TOPDIR}/example"
DEPENDS += " virtual/kernel linux-libc-headers "
do_install () {  
   ( cd ${TOPDIR}/example/Install ; ./install )
}

这是install脚本的相关部分:

if [ ! -d "/usr/src/kernel/include"  ]; then
  echo ERROR: Linux kernel source include directory not found.  
  exit 1
fi
cd /usr/src/kernel
make scripts
...
./install_drv pci ${DRV_ARGS}

我检查了更改为if [ ! -d "/usr/src/kernel" ],但也失败了。 install将不同的选项传递给install_drv,我有以下相关部分:

cd ${DRV_PATH}/pci
make NO_SYSFS=${ARG_NO_SYSFS} NO_INSTALL=${ARG_NO_INSTALL} ${ARGS_HWINT}
if [ ${ARG_NO_INSTALL} == 0 ]; then
  if [ `/sbin/lsmod | grep -ci "uceipci"` -eq 1 ]; then
    ./unload_pci
  fi
  ./load_pci DEBUG=${ARG_DEBUG}
fi

make中的build:目标${DRV_PATH}/pci基本上是这样的:

make -C /usr/src/kernel SUBDIRS=${PWD} modules

我的研究

我在linux-libc-headers.inc相关内发现了这些评论:

# You're probably looking here thinking you need to create some new copy
# of linux-libc-headers since you have your own custom kernel. To put 
# this simply, you DO NOT.
#
# Why? These headers are used to build the libc. If you customise the 
# headers you are customising the libc and the libc becomes machine
# specific. Most people do not add custom libc extensions to the kernel
# and have a machine specific libc.
#
# But you have some kernel headers you need for some driver? That is fine
# but get them from STAGING_KERNEL_DIR where the kernel installs itself.
# This will make the package using them machine specific but this is much
# better than having a machine specific C library. This does mean your 
# recipe needs a DEPENDS += "virtual/kernel" but again, that is fine and
# makes total sense.
#
# There can also be a case where your kernel extremely old and you want
# an older libc ABI for that old kernel. The headers installed by this
# recipe should still be a standard mainline kernel, not your own custom 
# one.

我有点不清楚我能不能得到&#39;来自STAGING_KERNEL_DIR的标题正确,因为我没有使用make。

kernel.bbclass目录中提供的meta/classes内,有这个变量分配:

# Define where the kernel headers are installed on the target as well as where
# they are staged.
KERNEL_SRC_PATH = "/usr/src/kernel"

然后,此路径将在此.bbclass文件中打包:

PACKAGES = "kernel kernel-base kernel-vmlinux kernel-image kernel-dev kernel-modules"
...
FILES_kernel-dev = "/boot/System.map* /boot/Module.symvers* /boot/config* ${KERNEL_SRC_PATH} /lib/modules/${KERNEL_VERSION}/build"

更新(1/21):

关于yocto IRC频道的建议是使用以下行:

do_configure[depends] += "virtual/kernel:do_shared_workdir"

Yocto Project Reference Manual证实,其中声明在版本1.8中,存在以下更改:

  

更改了内核构建过程,将源放在公共共享工作区中,并将构建工件单独放在源代码树中。从理论上讲,已经为内核配方中的大多数常见用法提供了迁移路径,但这可能并不适用于所有情况。特别是,用户需要确保在${S}${B}等函数中正确使用do_configure(源文件)和do_install(构建工件)。对于不从kernel-yocto继承或包含linux-yocto.inc的内核配方,您可能希望参考linux.inc图层中的meta-oe文件,了解您需要的各种更改使。作为参考,这里是linux.incmeta-oe文件更新的提交。

     

依赖内核源代码并且不继承模块类的配方可能需要在do_shared_workdir内核任务上添加显式依赖项,例如:

do_configure[depends] += "virtual/kernel:do_shared_workdir" 

但是我很难将这个应用到我的食谱中。根据我的理解,我应该能够将上述行更改为:

do_install[depends] += "virtual/kernel:do_shared_workdir"

这意味着do_install任务现在必须在do_shared_workdir配方的virtual/kernel任务之后运行,这意味着我应该能够使用共享的workdir(请参阅问题下面的3),但我仍然有相同的缺少内核头问题。

我的问题

我使用git.kernel.org的自定义Linux内核(v3.14)。它继承了kernel类。以下是我的一些问题:

  1. 不应该将包kernel-dev作为继承kernel类的任何配方的一部分吗? (this section变量词汇表)
  2. 如果我将virtual/kernel添加到DEPENDS变量,那是不是意味着kernel-dev会被引入?
  3. 如果kernel-dev是我食谱的依赖项的一部分,我是不是可以从我的食谱中指向/usr/src/kernel目录?根据{{​​3}},我认为我应该。
  4. 如何正确引用内核源头文件,最好不要更改安装脚本?

2 个答案:

答案 0 :(得分:13)

考虑您的环境

请记住,构建时环境中有不同的环境,包括:

  • sysroots
  • 对于内核,共享工作目录
  • 目标套餐

kernel-dev是一个目标包,您可以将其安装到目标系统的rootfs中,用于某些内容,例如perf / oprofile等分析工具所需的内核符号映射。它在构建时不存在,尽管它的一些内容在sysroots或shared workdir中可用。

指向正确的目录

您的do_install在构建时运行,因此它位于构建系统的构建目录结构中,而不是目标构建目录结构中。特别是,/usr/src/将不正确,它需要在您的构建目录中的某个路径。 virtual/kernel do_shared_workdir任务会填充${STAGING_DIR_KERNEL},因此您需要更改脚本中的该目录。

添加任务依赖

在:

do_install[depends] += "virtual/kernel:do_shared_workdir
假设do_configuredo_compile中没有任何内容访问那里的数据,

依赖性看起来对您的用例是正确的。

重新考虑module BitBake类

其他答案在查看module.bbclass的建议中是正确的,因为这说明了如何构建通用内核模块。如果你想使用自定义函数或make命令,这很好,你可以覆盖它们。如果你真的不想使用那个课程,我建议你从中获取灵感。

任务依赖性

virtual/kernel添加到DEPENDS表示virtual/kernel:do_populate_sysroot必须在do_configure任务之前运行。由于此处需要do_shared_workdir的依赖关系,DEPENDS上的virtual/kernel是不够的。

回答问题3

将构建kernel-dev包,但是需要将其安装到目标映像中并在运行时在真实目标上使用。在构建时需要这个,所以kernel-dev不合适。

其他建议

您可能希望kernel-devsrc包用于您正在执行的操作,而不是kernel-dev包。

答案 1 :(得分:1)

我认为没有人可以在这里正确回答最后一个问题。您使用的是非标准安装方法:我们无法知道如何与它进行交互...

那说,看一下meta / classes / module.bbclass的作用。它为make设置了几个相关变量:KERNEL_SRC=${STAGING_KERNEL_DIR}KERNEL_PATH=${STAGING_KERNEL_DIR}O=${STAGING_KERNEL_BUILDDIR}。也许您的安装程序支持其中一些环境变量,您可以在配方中设置它们吗?