Blog:
在 OpenEmbedded 中打内核补丁

2017年1月12日星期四
Linux
Linux
简介

尽管 OpenEmbedded/Yocto 一个用于生成镜像文件的很好的工具,但是利用这个编译系统来测试微小软件更改,却会变得复杂和缓慢。我建议可以单独更改内核然后编译,在项目的最后测试所有的变更,再往 OpenEmbedded/Yocto 中添加所做的修改。

为了演示这个方法,我们将往 Toradex 计算机模块 Colibri VF61 使用的内核中添加 NXP(之前的 Freescale)的惯性测量器 mma8653 驱动。

步骤

首选需要安装好 OpenEmbedded 以及所需的软件。你可以参考这个说明操作。

为了确定你的开发板所使用的内核版本,首先你可以查看不同开发板使用的内核 recipes。在本博文中,你也可以找到这些信息。

cd stuff
find . -wholename "*recipes-kernel/linux*.bb"

在这些结果中,我们感谢兴趣的文件位于 meta-toradex/recipes-kernel/linux/ 目录。对应目录中的文件如图 1 所示:

Page where a new repo is created
图 1:meta-toradex/recipes-kernel/linux/ 目录

正如你看到的,有许多不同版本的内核。在上面的目录中,使用下面命令查看,你的开发板使用的哪一个内核。结果如图 2 所示:

grep -nre "COMPATIBLE_MACHINE" *
Commands for synchronization
图 2: kernel recipes 和相应的开发板

有些开发板会使用多个内核。为了快速确定开发板正在使用的内核版本,你可以进入 build 目录,针对 kernel recipes 执行 bitbake 命令,这里使用 linux-toradex。在运行的过程中仔细观察,你会发现正在使用的 recipe,如图 3 所示(你也可以查找 PREFERRED_PROVIDER_virtual/kernel 变量):

bitbake linux-toradex
GitHub repositories tab
图 3:使用 bitbake 命令查看开发板使用的内核版本

现在我们知道所使用的 recipe,我们打开这个文件。下面是 stuff/meta-toradex/recipes-kernel/linux/linux-toradex_4.4.bb

require recipes-kernel/linux/linux-imx.inc
require recipes-kernel/linux/linux-dtb.inc
 
SUMMARY = "Linux kernel for Toradex Colibri VFxx Computer on Modules"
 
SRC_URI = "git://git.toradex.com/linux-toradex.git;protocol=git;branch=${SRCBRANCH} \
                      file://defconfig"
 
KERNEL_MODULE_AUTOLOAD += "${@bb.utils.contains('COMBINED_FEATURES', 'usbgadget', ' libcomposite', '',d)}"
 
LOCALVERSION = "-v2.6b2"
SRCBRANCH = "toradex_vf_4.4"
SRCREV = "efe965a5dad66bd14219cdc9474ea75eda783456"
DEPENDS += "lzop-native bc-native"
COMPATIBLE_MACHINE = "(vf)"

我们感兴趣的是 SRC_URI、SRCBRANCH 和 RCREV 变量。SRC_URI 指明从哪里下载内核源码以及使用哪一个配置文件。SRCBRANCH 是 SRC_URI 中 git repository 指向的分支。SRCREV 是分支使用的 commit。

我们复制相同的分支到电脑主机上,查看最后 5 个 commit 内容。结果如图 4 所示:

git clone -b 2015.04-toradex git://git.toradex.com/linux-toradex.git
 
git log -5 --pretty=oneline
GitHub repositories tab
图 4:内核源码中最后 5 个 commit

你需要选择和 OpenEmbedded 使用同样 commit 号的分支。SRCREV(以 efe 开头) 变量中有的 commit hash 值和 recipe的 SERCREV 是一致的。你可以使用 git branch --contains<githash> 命令看到。确保你使用了正确的分支。你可以创建新的分支来做更改:

git branch -b toradex_vf_4.4_mydev <githash>
进行更改并添加到 OpenEmbedded

本文章中将以 mma8653 加速度传感器驱动为例,并且也会将其添加到开发板的 device tree 中。

首先,针对开发板加载默认的配置:

export ARCH=arm
make colibri_vf_defconfig

然后,根据你的需要配置内核以及修改源代码。使用 menuconfig 使能加速度传感器驱动,如下面图 5 所示:

make menuconfig
GitHub repositories tab
图 5:使能 mma8452Q(兼容 mma8653)加速度传感器内核驱动

使用下面命令将配置保持到新的文件中:
make savedefconfig

目前的开发板配置将会使用保存到 defconfig 文件中。为了查看更改的内容,我们将配置文件和之前的备份文件做对比。结果如图 6 所示:

meld defconfig arch/arm/configs/colibri_vf_defconfig
GitHub repositories tab
图 6:使能 mma8452 驱动前后对比

唯一的更改是设置了 CONFIG_MMA8452。保持新的配置文件:

mv defconfig arch/arm/configs/colibri_vf_mma_8653_defconfig

同样 device tree 也需要一些修改。打开 arch/arm/boot/dts/vf-colibri-eval-v3.dtsi,修改 &i2c0 节点(127行)。红色的部分是所添加的内容:

&i2c0 {
        status = "okay";

        /* TouchRevolution Fusion 7 and 10 multi-touch controller */
        touch: touchrevf0710a@10 {
                compatible = "touchrevolution,fusion-f0710a";
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_gpiotouch>;
                reg = <0x10>;
                gpios = <&gpio0 30 GPIO_ACTIVE_HIGH /* SO-DIMM 28, Pen down interrupt */
                               &gpio0 23 GPIO_ACTIVE_LOW /* SO-DIMM 30, Reset interrupt */
                               >; status = "disabled"; }; /* M41T0M6 real time clock on carrier board */ rtc: m41t0m6@68 { compatible = "st,m41t00"; reg = <0x68>; }; mma8453fc@1d {
                compatible = "fsl,mma8653";
                reg = <0x1d>;
                pinctrl-0 = <&pinctrl_mma>;
                interrupt-parent = <&gpio1>;
                interrupts = <9 0>;
        };
};

并且添加下面的代码。放在 &iomuxc 节点中,位于文件的结尾处。更多关于 device tree 的定制信息可以从开发者中心网站查询到。

pinctrl_mma: mma {
                        fsl,pins = <
                                VF610_PAD_PTB19__GPIO_41        0x22ed
                        > ;
                };

提交你做的更改并创建一个补丁文件:

git commit -m "mma8653 accelerometer"
git format-patch --signoff HEAD~1

如果你有多个提交,可以改变上面数字 1 为你所作提交的次数。

复制补丁文件和 defconfig 文件到你使用 recipe 所在的目录,从而把相应的更改添加到 OpenEmbedded:

cp 0001-mma8653-accelerometer.patch /home/prjs/oe-core/stuff/meta-toradex/recipes-kernel/linux/linux-toradex-4.4/
 
cp arch/arm/configs/colibri_vf_mma8653 /home/prjs/oe-core/stuff/meta-toradex/recipes-kernel/linux/linux-toradex-4.4/defconfig

编辑 recipe 文件应用补丁,在 SRC_URI 中添加如下内容:

SRC_URI = "git://git.toradex.com/linux-toradex.git;protocol=git;branch=${SRCBRANCH} \
                      file://0001-mma8653-accelerometer.patch \
                      file://defconfig"

最后编译内核:

bitbake -c clean linux-toradex
bitbake virtual/kernel

内核和 device tree 都会部署到 out-glibc/deploy/images/colibri-vf/ 目录,如图 7 所示。你可以通过这篇文章的方法把他们部署到开发板上。

GitHub repositories tab
图 7:内核镜像、编译的模块和 device tree。
总结

正如文章开头所说的,在编译框架中编译内核是可行的,尽管有一些复杂。有对应的命令实现这种功能,但是需要对 OpenEmbedded/Yocto 有很好的了解,确保所需要的更改。

本文的主旨是向您演示可以在编译框架外通过编译和定制内核来隔离问题。希望本文对您有所帮助,下次见!

参考
作者: Leonardo Graboski Veiga, Toradex Brasil

评论

Please login to leave a comment!
Have a Question?