Beaglebone / Yocto / 内核配置

Beaglebone / Yocto / Kernel configuration

我想更改内核配置。

我创建了自己的层,在我的层内有一个 _%.bbappend 文件,它直接针对配方 linux-ti-staging.bb (link)。这个食谱构建了我的内核:

ziga@host:~/yocto/$ oe-pkgdata-util lookup-recipe kernel
linux-ti-staging

食谱是官方层的一部分meta-tilink)。

我的图层如下所示:

002--layers/meta--001/
├── conf
│   ├── distro
│   │   └── distro.conf
│   ├── layer.conf
│   └── machine
│       └── photovolt.conf
├── recipes-all
│   ├── application
│   │   └── application.bb
│   ├── image-003
│   │   └── image-003.bb
│   └── qtbase
│       └── qtbase_%.bbappend
├── recipes-bsp
│   └── u-boot
│       ├── u-boot-ti-staging
│       │   ├── 0001--add-fotovolt-dts-to-makefile.patch
│       │   └── photovolt.dts
│       └── u-boot-ti-staging_%.bbappend
└── recipes-kernel
    └── linux
        ├── linux-ti-staging
        │   ├── 0001--add-photovolt-dts-to-makefile.patch
        │   ├── 0002--disable-hdmi-node.patch
        │   ├── 0003--remove-conflicting-mmc-pinmuxing.patch
        │   ├── defconfig
        │   ├── fragment.cfg
        │   └── photovolt.dts
        └── linux-ti-staging_%.bbappend

我尝试按照官方 Yocto 参考 (link) 以其中描述的两种方式之一配置我的 _%.bbappend 文件。

1st - 使用配置片段

首先,我尝试使用 Linux 内核片段。我执行了:

ziga@host:~/yocto/$ bitbake -c menuconfig linux-ti-staging

在 kconfig/curses 界面中进行了配置,并将配置保存在默认名称 .config 下。然后我创建了一个 Linux 配置片段:

ziga@host:~/yocto/$ bitbake -c diffconfig linux-ti-staging

片段已创建,看起来像这样:

ziga@host:~/yocto/$ cat 003--builds/001--fotovolt/tmp/work/fotovolt-poky-linux-gnueabi/linux-ti-staging/5.10.65+gitAUTOINC+dcc6bedb2c-r22b/fragment.cfg
CONFIG_TOUCHSCREEN_ST1232=y

我将此片段复制到我的层,如第一个代码片段所示。现在根据官方参考,我还创建了 linux-ti-staging_%.bbappend (由 bitbake-layers 检测到),内容如下:

FILESEXTRAPATHS:prepend := "${THISDIR}/linux-ti-staging:"
SRC_URI += "file://fragment.cfg"

我希望 Yocto 可以像补丁一样对待 fragment.cfg 文件,但它什么也没做。


第二 - 使用整个配置

其次,我尝试使用整个 Linux 内核配置。我执行了:

ziga@host:~/yocto/$ bitbake -c menuconfig linux-ti-staging

在 kconfig/curses 界面中进行了配置,并以不同的名称保存配置,即 defconfig (7234 行):

ziga@host:~/yocto/$ wc -l 003--builds/001--fotovolt/tmp/work/fotovolt-poky-linux-gnueabi/linux-ti-staging/5.10.65+gitAUTOINC+dcc6bedb2c-r22b/build/.config
7234

我在我的图层中复制了这个 defconfig,从第一个代码片段可以看出。然后我根据官方 Yocto 参考手册编辑了我的 linux-ti-staging_%.bbappend,如下所示:

FILESEXTRAPATHS:prepend := "${THISDIR}/linux-ti-staging:"
SRC_URI += "file://defconfig"
KCONFIG_MODE = "alldefconfig"

但这也行不通。


我在建造前打扫过

在这两种情况下,我都使用了两个命令来干净地构建所有内容:

bitbake -c cleansstate virtual/kernel
bitbake image-003

但这对内核配置完全没有任何作用。我可以通过 (a) 登录 运行 目标,(b) 在某处提取 /proc/config.gz 和 (c) 读取获得的 config 文件来验证没有应用任何更改。文件与原来相同...

那么,我怎样才能永久修改内核配置呢?


机器

我的 MACHINE 是在 photovolt.conf 中定义的,它基本上重用了来自官方层 meta-ti 的机器 beaglebone (link)。它看起来像这样:

#@TYPE: Machine
#@NAME: Photovolt machine - Beaglebone based machine
#@DESCRIPTION: Machine configuration for my machine

require conf/machine/beaglebone.conf

KERNEL_DEVICETREE = "photovolt.dtb"
UBOOT_MACHINE = "photovolt_defconfig"

分布

我使用的发行版在 distro.conf 中定义如下:

require conf/distro/poky.conf

DISTRO = "distro"
DISTRO_NAME = "Distro (Yocto derived GNU/Linux distribution)"
DISTRO_VERSION = "1.0.0"
DISTRO_CODENAME = "Heart I"
MAINTAINER = "Me <me.me@gmail.com>"
  
DISTRO_FEATURES:append = " systemd"
DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"
VIRTUAL-RUNTIME:init_manager = "systemd"
VIRTUAL-RUNTIME:initscripts = ""
   
PREFERRED_PROVIDER:virtual/libgbm = "mesa"

食谱看起来很奇怪

食谱linux-ti-stagging.bb (link) 乍一看很简单,但它确实有些可疑。它首先requires一个setup-defconfig.inc(link)里面有个任务do_configure()。这里它做了一些复制操作,它还使用了一个奇怪的 defconfig 文件 (link)。也许这与我的问题有某种联系...

你的目录结构应该是这样的

meta-something
└── recipes-kernel
    └── linux
        ├── files
        │   └── defconfig
        └── linux-ti-staging.bbappend

linux-ti-staging.bbappend

FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI += "file://defconfig"

setup-defconfig.inc 中很明显,他们在 do_configure 中使用以下部分处理配置片段:

# Fourth, handle config fragments specified in the recipe
    # The assumption is that the config fragment will be specified with the absolute path.
    # E.g. ${WORKDIR}/config1.cfg or ${S}/config2.cfg
    if [ -n "${KERNEL_CONFIG_FRAGMENTS}" ]
    then
        for f in ${KERNEL_CONFIG_FRAGMENTS}
        do
            # Check if the config fragment is available
            if [ ! -e "$f" ]
            then
                echo "Could not find kernel config fragment $f"
                exit 1
            fi
        done
    fi

    # Now that all the fragments are located merge them
    if [ -n "${KERNEL_CONFIG_FRAGMENTS}" -o -n "$configfrags" ]
    then
        ( cd ${WORKDIR} && ${S}/scripts/kconfig/merge_config.sh -m -r -O ${B} ${B}/.config $configfrags ${KERNEL_CONFIG_FRAGMENTS} 1>&2 )
        yes '' | oe_runmake -C ${S} O=${B} oldconfig
    fi

所以,这里是对它的作用的解释:

  • 检查变量KERNEL_CONFIG_FRAGMENTS是否有内容
  • 如果是,它会检查其内容(文件)是否存在
  • KERNEL_CONFIG_FRAGMENTSconfigfrags 的所有配置片段合并到 ${B}/.config 中,这是将要构建的最终配置

configfrags 只是用来保存从其他 defconfig 文件中提取的片段。这对你的情况无关紧要。

因此,您可以在 linux-ti-staging_%.bbappend 中执行以下操作:

FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI += "file://fragment.cfg"
KERNEL_CONFIG_FRAGMENTS += "${WORKDIR}/fragment.cfg"

由于他们直接检查 KERNEL_CONFIG_FRAGMENTS 的内容,如果您不设置 ${WORKDIR} 就会失败。

${WORKDIR}fragment.cfg 将被解包的地方。

因此,根据他们在 do_configure 上使用的内容,KERNEL_CONFIG_FRAGMENTS 上的测试应该会通过,因为它将包含内容,并且会将其配置合并到配置文件中 ${B}/.config.

要检查,在 do_configure 之后只需检查 ${B}/.config 的内容以获取新的片段内容。

警报 您需要将片段文件中的第一行保留为空行。因为 merge_config.sh 将跳过它。

因此,您的片段将如下所示:


CONFIG_TOUCHSCREEN_ST1232=y

如果这不起作用,请尝试添加此自定义函数以将您的 fragment.cfg 应用到最终配置文件中:

  • linux-ti-staging_%.bbappend:
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI += "file://fragment.cfg"

CUSTOM_FRAGMENTS += "fragment.cfg"

do_merge_fragment(){
   for f in ${CUSTOM_FRAGMENTS}; do
       if [ -f "${WORKDIR}/${f}" ]; then
           ${S}/scripts/kconfig/merge_config.sh -m ${B}/.config ${WORKDIR}/${f}
       fi
   done
}

addtask merge_fragment after do_configure before do_compile

有了它,您将确保应用该片段。