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

kar*_*bar 11 header-files linux-kernel openembedded bitbake yocto

介绍

do_install在BitBake配方中有一个任务,我为驱动程序编写了执行自定义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 )
}
Run Code Online (Sandbox Code Playgroud)

这是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}
Run Code Online (Sandbox Code Playgroud)

我检查了改变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
Run Code Online (Sandbox Code Playgroud)

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

make -C /usr/src/kernel SUBDIRS=${PWD} modules
Run Code Online (Sandbox Code Playgroud)

我的研究

我发现这些评论是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.
Run Code Online (Sandbox Code Playgroud)

我有点不清楚我是否可以" 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"
Run Code Online (Sandbox Code Playgroud)

然后在此.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"
Run Code Online (Sandbox Code Playgroud)

更新(1/21):

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

do_configure[depends] += "virtual/kernel:do_shared_workdir"
Run Code Online (Sandbox Code Playgroud)

Yocto项目参考手册证实了这一点,该手册指出在1.8版本中,有以下变化:

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

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

do_configure[depends] += "virtual/kernel:do_shared_workdir" 
Run Code Online (Sandbox Code Playgroud)

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

do_install[depends] += "virtual/kernel:do_shared_workdir"
Run Code Online (Sandbox Code Playgroud)

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

我的问题

我使用的是从定制的Linux内核(v3.14)git.kernel.org.继承了这个kernel类.以下是我的一些问题:

  1. 包不应该kernel-dev是继承kernel该类的任何配方的一部分吗?(这部分变量词汇表)
  2. 如果我将变量添加virtual/kernelDEPENDS变量中,那是不是意味着它kernel-dev会被引入?
  3. 如果kernel-dev是我的食谱的依赖项的一部分,我不能指向/usr/src/kernel我的食谱目录?根据Yocto邮件列表上的回复,我想我应该.
  4. 如何正确引用内核源头文件,最好不要更改安装脚本?

小智 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
Run Code Online (Sandbox Code Playgroud)

依赖性看起来对你的用例是正确的,假设没有任何内容do_configuredo_compile访问那里的数据.

重新考虑moduleBitBake类

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

任务依赖项

添加virtual/kernelDEPENDS手段virtual/kernel:do_populate_sysroot必须在我们的do_configure任务之前运行.因为你需要一个依赖do_shared_workdir,所以一个DEPENDSon virtual/kernel是不够的.

回答问题3

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

其他建议

你可能想要kernel-devsrc你正在做的kernel-dev包,而不是包.