By Toradex秦海
1). 简介
嵌入式设备采用Embedded Linux操作系统进行开发已经越来越成为主流,但是如何将开发完成的Linux uboot/kernel配置,以及应用程序整合到Embedded Linux镜像中以便在量产的时候更方便的更新到嵌入式设备中可能是很多嵌入式开发者面临的挑战之一,而本文就以在Embedded Linux中使用比较广泛的Yocto project为例,基于Openembedded开发框架定制 Embedded Linux镜像。
本文所演示的平台来自于Toradex Colibri iMX6嵌入式平台,这个平台是基于NXP iMX6系列ARM处理器,核心为Cortex-A9。同时Toradex也提供了一个完整的Ycoto project兼容的基于Openembedded发布的Embedded Linux,这样就无需完全从头开始配置自己的layer,只需要修改添加需要的部分即可。
2. 准备
a). Colibri iMX6 ARM核心版配合Colibri Eva Board 载板,用于测试编译好的image。
b). 配置Openembedded开发环境,请参考这里说明,本文测试使用LinuxImage2.7分支环境。
c). 参考这里说明下载Linux V2.7内核和uboot源代码,用于产生相应的patch文件。
c). 本文演示的定制Embedded Linux镜像主要添加修改以下内容,下面会按照这个内容逐一说明:
./ 修改uboot默认环境变量,适配演示使用的 LVDS 液晶屏
./ 修改Linux Kernel增加一个设备驱动;同时修改Linux device tree文件,增加两个串口配置
./ 将演示Qt应用程序集成到image,并配置为开机自动启动
3). 创建定制Embedded Linux 相关配置Layer
a). 在配置下载好的OpenEmbedded环境Layer目录下,创建存放本次定制image相关文件资料的Layer – meta-toradex-custom.
b). 在meta-toradex-custom目录下创建 conf 目录,并创建Layer配置文件 layer.conf ,这个文件内容可以参考meta-toradex-nxp/conf/layer.conf 文件进行修改,主要是layer名字和优先级以及依赖部分需要注意,修改好的文件请见如下:
https://github.com/simonqin09/openembedded_demo/blob/master/meta-toradex-custom/conf/layer.conf
c). 在 conf 目录下创建 machine 目录,并创建 machine 配置文件 colibri-imx6-custom.conf , 文件内容同样参考meta-toradex-nxp/conf/machine/colibri-imx6.conf 修改,本文因没有修改device tree名字,因此没有修改次文件,内容如下:
https://github.com/simonqin09/openembedded_demo/blob/master/meta-toradex-custom/conf/machine/colibri-imx6-custom.conf
4). OpenEmbedded下Uboot修改示例
a). 因为演示使用的LVDS液晶屏分辨率为1024x768,这里将uboot显示环境变量默认值修改为对应分辨率
b). 首先进入下载的uboot源代码对 include/configs/colibri_imx6.h 文件进行修改,产生的patch文件如下:
https://github.com/simonqin09/openembedded_demo/blob/master/meta-toradex-custom/recipes-bsp/u-boot/files/colibri_imx6_uboot_custom.patch
c). 在 meta-toradex-custom layer目录下创建 recipes-bsp/u-boot目录,并对 u-boot-toradex_2016.11.bb 文件进行append,增加上面生成的patch内容,如下:
https://github.com/simonqin09/openembedded_demo/blob/master/meta-toradex-custom/recipes-bsp/u-boot/u-boot-toradex_2016.11.bbappend
5). OpenEmbedded下Linux kernel 和 device tree 修改示例
a). 对Linux kernel进行重新config,增加了如下RTL8152 USB Ethernet Adapter驱动
--------------------------------
→ Device Drivers → Network device support → USB Network Adapters
<*> Realtek RTL8152/RTL8153 Based USB Ethernet Adapters
--------------------------------
生成的新的defconfig文件如下:
https://github.com/simonqin09/openembedded_demo/blob/master/meta-toradex-custom/recipes-kernel/linux/files/defconfig
b). 对 arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts文件进行修改,增加UART4 和 UART5 连个串口支持,关于Colibri iMX6串口详细说明请参考这里,修改后的 patch 文件0001-custom-devicetree.patch 请见如下:
https://github.com/simonqin09/openembedded_demo/blob/master/meta-toradex-custom/recipes-kernel/linux/files/0001-custom-devicetree.patch
c). 在 meta-toradex-custom layer目录下创建 recipes-kernel/linux目录,并对 linux-toradex_4.1-2.0.x.bb 文件进行append,将上面生成的 defconfig 和 0001-custom-devicetree.patch增加进去,如下:
https://github.com/simonqin09/openembedded_demo/blob/master/meta-toradex-custom/recipes-kernel/linux/linux-toradex_4.1-2.0.x.bbappend
然后再创建 files 目录,将defconfig 和 0001-custom-devicetree.patch 两个文件复制进去。
另外,关于如何生成kernel patch,也可以参考下面文章:
https://www.toradex.cn/blog/patching-kernel-in-openembedded
6). OpenEmbedded下部署Qt应用示例
a). 本文所使用的Qt 应用demo说明请参考下面文章:
http://blog.sina.com.cn/s/blog_d733e5170102wyay.html
b). 配置Qt开机自启动需要下面两个文件
./ Qt 程序执行脚本,这里使用linuxfb进行显示
https://github.com/simonqin09/QtGPIOProject/blob/master/qtdemo.sh
./ Systemd 启动配置 .service文件
https://github.com/simonqin09/QtGPIOProject/blob/master/qtdemo_launch.service
c). 在 meta-toradex-custom layer目录下创建 recipes-qt/qtdemo目录,并创建如下 qtdemo_0.1.bb 文件用于从Qt 应用的git地址下载应用并编译部署
https://github.com/simonqin09/openembedded_demo/blob/master/meta-toradex-custom/recipes-qt/qtdemo/qtdemo_0.1.bb
关于这个bb文件的详细说明,可以参考下面文档:
https://www.toradex.cn/blog/building-custom-embedded-linux-distributions
7). OpenEmbedded下设置自定义image镜像编译
a). 在 meta-toradex-custom layer目录下创建 recipes-images/images目录,将下面三个文件从 meta-toradex-demos/recipes-images/images 复制过来
--------------------------------
angstrom-qt5-x11-image.bb
tdx-extra.inc
tdx-image-fstype.inc
--------------------------------
Angstrom-qt5-x11-image.bb 文件就是生成image的bb文件,可以不做修改,也可以根据需要添加修改package设定,本文修改了angstrom-qt5-x11-image.bb文件,将默认需要编译的Qt demo smarthome 程序去掉了,如下:
https://github.com/simonqin09/openembedded_demo/blob/master/meta-toradex-custom/recipes-images/images/angstrom-qt5-x11-image.bb
b). 在images目录下继续创建 files/colibri-imx6-custom 目录,将 update.sh 文件从 meta-toradex-demos/recipes-images/images/files/colibri-imx6 复制过来。然后因为 machine 名字变为colibri-imx6-custom 了,因此要对应修改,修改内容如下:
https://github.com/simonqin09/openembedded_demo/blob/master/meta-toradex-custom/recipes-images/images/update.sh.patch
c). 在colibri-imx6-custom目录下继续创建 imx_flash 目录,将 meta-toradex-demos/recipes-images/images/files/colibri-imx6/files/imx_flash目录下的文件复制过来。
d). 在colibri-imx6-custom目录下继续创建 colibri-imx6-custom_bin 目录,将meta-toradex-demos/recipes-images/images/files/colibri-imx6/files/colibri-imx6_bin目录下的所有文件复制过来。
e). 至此,meta-toradex-custom layer 的所有修改都已经完成,下面我们进入 OpenEmbedded编译环境下 build/conf 目录, 对下面两个文件进行修改:
./ bblayers.conf – 增加了meta-toradex-custom layer进来,如下:
https://github.com/simonqin09/openembedded_demo/blob/master/bblayers.conf
./ local.conf – 将默认的machine 修改为colibri-imx6-custom, 同时增加了一些包如 tslib 和 linuxfb,如下:
https://github.com/simonqin09/openembedded_demo/blob/master/local.conf
f). 在 build目录下执行下面命令进行编译,编译成功后,可以在deploy/images/colibri-imx6-custom 目录下找到编译好的 image 压缩包。
--------------------------------
$ bitbake –k angstrom-qt5-x11-image
--------------------------------
8). 在Colibri imx6模块上面更新image并测试
a). 将上述生成好的image文件colibri-imx6-custom_Qt5-X11-Image_2.7b3-xxxxxxxx.tar.bz2 按照这里的说明更新到 Colibri iMX6 模块上面去。
b). QT GPIO 应用使用的管脚为SODIMM PIN 127,这里在 Colibri Evaluation Board 上面将 X10 SODIMM 127 和 X21 LED1 相连,用于测试GPIO电平情况。
c). image 更新好后,我们可以逐项去测试上面每一个配置
./ uboot
如下可见默认环境变量的修改已经生效
--------------------------------
# env default –a
# printenv
…
vidargs=video=mxcfb0:dev=lcd,1024x768M@60,if=RGB666 video=mxcfb1:off fbmem=8M
…
--------------------------------
./ kernel config 修改
如下可见kernel增加的驱动也已经编译进去了
--------------------------------
root@colibri-imx6-custom:~# zcat /proc/config.gz |grep RTL8152
CONFIG_USB_RTL8152=y
--------------------------------
./ device tree 修改
如下可见,除了默认的ttymxc0-2设备,还多了ttymxc3和ttymxc4
--------------------------------
root@colibri-imx6-custom:~# ls /dev/ttymxc*
/dev/ttymxc0 /dev/ttymxc1 /dev/ttymxc2 /dev/ttymxc3 /dev/ttymxc4
--------------------------------
./ Qt 程序自启动以及控制GPIO情况
如下图片
还有一起启动过程的视频如下:
http://v.youku.com/v_show/id_XMzE3MDY4NDkyNA==.html
9). 总结
本文只是简单演示了利用 OpenEmbedded 可以非常方便的生成定制化 Embedded Linux,另外配合git,还可以很好的实现不同版本的管理。但是 OpenEmbedded 架构本身也是比较复杂的,要想灵活使用还需要对其做一些深入的学习才能得心应手。