图像识别DM8127开发攻略——KERNEL的移植说明

接上一篇《图像识别DM8127开发攻略——UBOOT的移植说明》的步伐,DM8127开发攻略最后一篇文章是有关Kernel的裁剪移植。基于APPRO RDK3.8.0的基础上,我们对/ti_tools/ipnc_psp_arago/kernel进行裁剪和移植,这个kernel是linux-2.6.37版本:
一、第一步还是做裁剪工作,删除多余的文件夹和文件,方便程序在每个阶段备份保存。
1、先在kernel/fs/hostf/Makefile里,打开Makefile文件,屏蔽#include arch/um/scripts/Makefile.rules,见下图路径,
图像识别DM8127开发攻略——KERNEL的移植说明_第1张图片
然后删除kernel/arch/um文件夹,只保留下图的内容:
图像识别DM8127开发攻略——KERNEL的移植说明_第2张图片
2、删除kernel/arch/x86里面的文件,只保留下图的内容:
图像识别DM8127开发攻略——KERNEL的移植说明_第3张图片
3、删除kernel/arch/arm/里面的内容,只保留下图内容:
图像识别DM8127开发攻略——KERNEL的移植说明_第4张图片

4、删除kernel/arch/arm/mach-omap2/里面的内容以board-开头一些的文件,只保留下图几个board-xxx.c
图像识别DM8127开发攻略——KERNEL的移植说明_第5张图片
Board-ti8148ipnc.c就是重点要修改的平台文件,其他不相关的平台C文件都去掉。
5、删除arch/arm/configs多余平台配置文件:
图像识别DM8127开发攻略——KERNEL的移植说明_第6张图片
只保留ti8148_ipnc_ubifs_defconfig文件

6、删除上面提到的文件夹和文件,那么有关的脚本文件需要同步修改,
A、arch/arm/Makefile修改
第129行开始:
ifeq ($(CONFIG_TY_KERNEL),y) (本人用这种方式屏蔽里面的内容,不编译)
machine-$(CONFIG_ARCH_AAEC2000) := aaec2000
machine-$(CONFIG_ARCH_AT91) := at91
machine-$(CONFIG_ARCH_BCMRING) := bcmring
machine-$(CONFIG_ARCH_CLPS711X) := clps711x
machine-$(CONFIG_ARCH_CNS3XXX) := cns3xxx
machine-$(CONFIG_ARCH_DAVINCI) := davinci
machine-$(CONFIG_ARCH_DOVE) := dove
machine-$(CONFIG_ARCH_EBSA110) := ebsa110
machine-$(CONFIG_ARCH_EP93XX) := ep93xx
machine-$(CONFIG_ARCH_GEMINI) := gemini
machine-$(CONFIG_ARCH_H720X) := h720x
machine-$(CONFIG_ARCH_INTEGRATOR) := integrator
machine-$(CONFIG_ARCH_IOP13XX) := iop13xx
machine-$(CONFIG_ARCH_IOP32X) := iop32x
machine-$(CONFIG_ARCH_IOP33X) := iop33x
machine-$(CONFIG_ARCH_IXP2000) := ixp2000
machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx
machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx
machine-$(CONFIG_ARCH_KIRKWOOD) := kirkwood
machine-$(CONFIG_ARCH_KS8695) := ks8695
machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x
machine-$(CONFIG_ARCH_LOKI) := loki
machine-$(CONFIG_ARCH_LPC32XX) := lpc32xx
machine-$(CONFIG_ARCH_MMP) := mmp
machine-$(CONFIG_ARCH_MSM) := msm
machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0
machine-$(CONFIG_ARCH_MX1) := imx
machine-$(CONFIG_ARCH_MX2) := imx
machine-$(CONFIG_ARCH_MX25) := mx25
machine-$(CONFIG_ARCH_MX3) := mx3
machine-$(CONFIG_ARCH_MX5) := mx5
machine-$(CONFIG_ARCH_MXC91231) := mxc91231
machine-$(CONFIG_ARCH_NETX) := netx
machine-$(CONFIG_ARCH_NOMADIK) := nomadik
machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx
machine-$(CONFIG_ARCH_OMAP1) := omap1
machine-$(CONFIG_ARCH_OMAP2) := omap2
machine-$(CONFIG_ARCH_OMAP3) := omap2
machine-$(CONFIG_ARCH_OMAP4) := omap2
machine-$(CONFIG_ARCH_ORION5X) := orion5x
machine-$(CONFIG_ARCH_PNX4008) := pnx4008
machine-$(CONFIG_ARCH_PXA) := pxa
machine-$(CONFIG_ARCH_REALVIEW) := realview
machine-$(CONFIG_ARCH_RPC) := rpc
machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2416 s3c2440 s3c2443
machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0
machine-$(CONFIG_ARCH_S3C64XX) := s3c64xx
machine-$(CONFIG_ARCH_S5P64X0) := s5p64x0
machine-$(CONFIG_ARCH_S5P6442) := s5p6442
machine-$(CONFIG_ARCH_S5PC100) := s5pc100
machine-$(CONFIG_ARCH_S5PV210) := s5pv210
machine-$(CONFIG_ARCH_S5PV310) := s5pv310
machine-$(CONFIG_ARCH_SA1100) := sa1100
machine-$(CONFIG_ARCH_SHARK) := shark
machine-$(CONFIG_ARCH_SHMOBILE) := shmobile
machine-$(CONFIG_ARCH_STMP378X) := stmp378x
machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx
machine-$(CONFIG_ARCH_TCC8K) := tcc8k
machine-$(CONFIG_ARCH_TEGRA) := tegra
machine-$(CONFIG_ARCH_U300) := u300
machine-$(CONFIG_ARCH_U8500) := ux500
machine-$(CONFIG_ARCH_VERSATILE) := versatile
machine-$(CONFIG_ARCH_VEXPRESS) := vexpress
machine-$(CONFIG_ARCH_W90X900) := w90x900
machine-$(CONFIG_ARCH_NUC93X) := nuc93x
machine-$(CONFIG_FOOTBRIDGE) := footbridge
machine-$(CONFIG_MACH_SPEAR300) := spear3xx
machine-$(CONFIG_MACH_SPEAR310) := spear3xx
machine-$(CONFIG_MACH_SPEAR320) := spear3xx
machine-$(CONFIG_MACH_SPEAR600) := spear6xx
endif

machine-$(CONFIG_ARCHTI81XX) := omap2 (这里把需要编译的TI81XX 对应的omap2提取出来)
(还有下面的使用#号屏蔽不需要的平台)
#Platform directory name. This list is sorted alphanumerically
#by CONFIG
* macro name.
#plat-$(CONFIG_ARCH_MXC) := mxc
plat-$(CONFIG_ARCH_OMAP) := omap (这里需要编译,不能屏蔽)
#plat-$(CONFIG_ARCH_S3C64XX) := samsung
#plat-$(CONFIG_ARCH_STMP3XXX) := stmp3xxx
#plat-$(CONFIG_ARCH_TCC_926) := tcc
#plat-$(CONFIG_PLAT_IOP) := iop
#plat-$(CONFIG_PLAT_NOMADIK) := nomadik
#plat-$(CONFIG_PLAT_ORION) := orion
#plat-$(CONFIG_PLAT_PXA) := pxa
#plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx samsung
#plat-$(CONFIG_PLAT_S5P) := s5p samsung
#plat-$(CONFIG_PLAT_SPEAR) := spear
#plat-$(CONFIG_PLAT_VERSATILE) := versatile

B、arch/arm/Kconfig修改
从第869行开始:
(使用#号屏蔽不相关的平台Kconfig文件,让它们不参与编译)
#source "arch/arm/mach-aaec2000/Kconfig"

#source "arch/arm/mach-at91/Kconfig"

#source "arch/arm/mach-bcmring/Kconfig"

#source "arch/arm/mach-clps711x/Kconfig"

#source "arch/arm/mach-cns3xxx/Kconfig"

#source "arch/arm/mach-davinci/Kconfig"

#source "arch/arm/mach-dove/Kconfig"

#source "arch/arm/mach-ep93xx/Kconfig"

#source "arch/arm/mach-footbridge/Kconfig"

#source "arch/arm/mach-gemini/Kconfig"

#source "arch/arm/mach-h720x/Kconfig"

#source "arch/arm/mach-integrator/Kconfig"

#source "arch/arm/mach-iop32x/Kconfig"

#source "arch/arm/mach-iop33x/Kconfig"

#source "arch/arm/mach-iop13xx/Kconfig"

#source "arch/arm/mach-ixp4xx/Kconfig"

#source "arch/arm/mach-ixp2000/Kconfig"

#source "arch/arm/mach-ixp23xx/Kconfig"

#source "arch/arm/mach-kirkwood/Kconfig"

#source "arch/arm/mach-ks8695/Kconfig"

#source "arch/arm/mach-lh7a40x/Kconfig"

#source "arch/arm/mach-loki/Kconfig"

#source "arch/arm/mach-lpc32xx/Kconfig"

#source "arch/arm/mach-msm/Kconfig"

#source "arch/arm/mach-mv78xx0/Kconfig"

#source "arch/arm/plat-mxc/Kconfig"

#source "arch/arm/mach-netx/Kconfig"

#source "arch/arm/mach-nomadik/Kconfig"
#source "arch/arm/plat-nomadik/Kconfig"

#source "arch/arm/mach-ns9xxx/Kconfig"

#source "arch/arm/mach-nuc93x/Kconfig"

source "arch/arm/plat-omap/Kconfig"

#source "arch/arm/mach-omap1/Kconfig"

source "arch/arm/mach-omap2/Kconfig" (这个是DM8127平台的,不能屏蔽)

#source "arch/arm/mach-orion5x/Kconfig"

#source "arch/arm/mach-pxa/Kconfig"
#source "arch/arm/plat-pxa/Kconfig"

#source "arch/arm/mach-mmp/Kconfig"

#source "arch/arm/mach-realview/Kconfig"

#source "arch/arm/mach-sa1100/Kconfig"

#source "arch/arm/plat-samsung/Kconfig"
#source "arch/arm/plat-s3c24xx/Kconfig"
#source "arch/arm/plat-s5p/Kconfig"

#source "arch/arm/plat-spear/Kconfig"

#source "arch/arm/plat-tcc/Kconfig"

#if ARCH_S3C2410
#source "arch/arm/mach-s3c2400/Kconfig"
#source "arch/arm/mach-s3c2410/Kconfig"
#source "arch/arm/mach-s3c2412/Kconfig"
#source "arch/arm/mach-s3c2416/Kconfig"
#source "arch/arm/mach-s3c2440/Kconfig"
#source "arch/arm/mach-s3c2443/Kconfig"
#endif

#if ARCH_S3C64XX
#source "arch/arm/mach-s3c64xx/Kconfig"
#endif

#source "arch/arm/mach-s5p64x0/Kconfig"

#source "arch/arm/mach-s5p6442/Kconfig"

#source "arch/arm/mach-s5pc100/Kconfig"

#source "arch/arm/mach-s5pv210/Kconfig"

#source "arch/arm/mach-s5pv310/Kconfig"

#source "arch/arm/mach-shmobile/Kconfig"

#source "arch/arm/plat-stmp3xxx/Kconfig"

#source "arch/arm/mach-tegra/Kconfig"

#source "arch/arm/mach-u300/Kconfig"

#source "arch/arm/mach-ux500/Kconfig"

#source "arch/arm/mach-versatile/Kconfig"

#source "arch/arm/mach-vexpress/Kconfig"

#source "arch/arm/mach-w90x900/Kconfig"

上面对arch/arm/Kconfig的修改,基本保证不相关平台从内核删除掉。

7、还有两个提到的编译需要注意的地方:
在ubuntu16.04版本的虚拟机环境下,除了在《图像识别DM8127开发攻略——开发环境搭建》提到的#apt-get install libncurses (注意号要带上)安装外,还有个地方需要修改:
在内核源码kernel/kernel/timeconst.pl
第373行需要修改:
#if (!defined(@val)) { #Jingbo (这里需要屏蔽)
if ((!@val)) { (改成这个样子)
否则无法在我们的ubuntu16.04正常编译linux-2.6.37。

8、内核编译还需要u-boot的mkimage工具
这里要提到一点,在RDK开发包中,编译kernel的时候,必须要先编译前面提到u-boot,即正常的ubootbin,而且不能使用ubootclean,否则这里编译kernel会编译不通过,因为编译kernel得到uImage二进制BIN文件的时候,需要用到uboot里面的工具,比如: mkimage工具。

二、编译工作
本人在《图像识别DM8127开发攻略 ——RDK软件架构浅析及编译》里面提到SDK的编译过程,我们看到里面有3个编译脚本是和kernel相关的。

build_3_kernel-menuconfig.sh、build_3_kernel-all.sh、build_3_kernel-tmp.sh
这里就不累赘介绍了,见链接文章:
https://blog.51cto.com/zjbintsystem/2043380
那里面有详细介绍这三个.sh脚本功能。

三、DM8127平台软件修改

涉及到平台的有三个重要的文件,arch/arm/mach-omap2/board-ti8148ipnc.c、devices.c和mux814x.c还是管脚复用问题,DM8127有些PIN脚用来接CMOS,就不能配置成GPIO模式,有些PIN脚用作HDMI视频输出,也不能配置成GPIO,MMC有两组,我们只需要MMC1第一组做SD卡信号接口,这里也不能配置成GPIO,而第2组MMC2我们不想支持两路SD卡信号,就可以配置成GPIO模式,还有gpmc_ad就得配置成接NAND FLASH的接口,等等。这些功能定义首先在这三个文件先去做,注意mux814x.c那个数组struct omap_mux __initdata ti814x_muxmodes[],里面涉及到其他DM385,TI811X平台等等,源码有提示哪一行定义用不上。
这里举个例子:
在mux814x.c里,ti814x_muxmodes[]后面添加
_TI814X_MUXENTRY(MMC2_DAT3, 0,
"MMC2_DAT3", NULL, NULL, NULL, NULL, NULL, NULL, "GP2_5_work_state",
NULL, NULL, NULL, NULL), (我们想使用GP2_5用做GPIO进行LED灯控制)
/manual reset/
_TI814X_MUXENTRY(OSC_WAKE, 0,
"osc_wake", "spi1_cs1", NULL, NULL, NULL, NULL,
"timer5_mux1", "GP1_7_manual_reset", NULL, NULL, NULL, NULL),
(GP1_7我们用做按键输入)
_TI814X_MUXENTRY这个格式我们在后面添加,其实在前面已经有定义的,可以通过查找MMC2_DAT3和OSC_WAKE就能找到,我们这里再次添加,只是不想破坏TI 的软件架构,同时加上我们的信息:GP2_5_work_state和GP1_7_manual_reset。那么把这两句添加到ti814x_muxmodes[]后面,就必须在board-ti8148ipnc.c ti8148_ipnc_init()函数后面对应添加
/work state/
omap_mux_init_signal("GP2_5_work_state", TI814X_PIN_OUTPUT_PULL_DIS);

error = gpio_request(GP2_5_WORK_STATE, "WORK_STATE");
if (error < 0) {
    printk(KERN_ERR "%s: failed to request GP2_5_WORK_STATE for WORK_STATE"
        ": %d\n", __func__, error);
    return;
}

/*manual reset*/
omap_mux_init_signal("GP1_7_manual_reset", TI814X_PIN_INPUT_PULL_UP);

error = gpio_request(GP1_7_MANUAL_RESET, "MANUAL_RESET");
if (error < 0) {
    printk(KERN_ERR "%s: failed to request GP1_7_MANUAL_RESET for MANUAL_RESET"
        ": %d\n", __func__, error);
    return;
}

/work state/
gpio_direction_output(GP2_5_WORK_STATE, 1);(这里必须配置成输出模式)
/manual reset/
gpio_direction_input(GP1_7_MANUAL_RESET);(这里必须配制成输入模式)

其中:
#define GP2_5_WORK_STATE (69) //GP2_5 work state
#define GP1_7_MANUAL_RESET (39) //GP1_7 manual reset

首先omap_mux_init_signal()调用ti814x_muxmodes[],那么GP2_5这个管脚就配置成GPIO输出模式,GP1_7就配置成GPIO输入模式,同时必须调用gpio_request函数,先申请,才能使用。
这里提到一点,TI DM8127 4组GPIO index是这样管理:第一组GPIO0是0-31,第二组GPIO1是32-63,第三组GPIO2是64-95,第四组GPIO3是96-127。所以上面GP2_5的宏定义值是69(69-32-32=5), GP1_7宏定义是39(39-32=7),本人这样写应该看得明白。
同样,arch/arm/mach-omap2/devices.c就是对各个功能模块做类似的管脚配置工作,比如DM8127支持CAN总线,则在:
static void ti814x_d_can_init(unsigned int instance)
{
omap_mux_init_signal("dcan0_tx.dcan0_tx", 0);
omap_mux_init_signal("dcan0_rx.dcan0_rx", TI814X_INPUT_EN |
TI814X_PULL_UP);
d_can_hw_raminit(instance);
platform_device_register(&ti814x_d_can0_device);
}
进行配置,同时在omap2_init_devices()函数调用ti814x_d_can_init()初始化,内核运行最先去做arch/arm/mach-omap2/board-ti8148ipnc.c 里的ti8148_ipnc_init()和arch/arm/mach-omap2/devices.c里的omap2_init_devices()函数的初始化。做完DM8127管脚的功能配置,内核才开始去做对应外设芯片的初始化工作(驱动程序)。
除了在CORTEX-A8 核可以对管脚复用寄存器配置,另外两个M3核(M3-ISS和M3-HDVPSS)也可以对管脚复用寄存器进行配置,这一点要注意,也很讨厌,有时我们在内核配置好的寄存器,结果在运行APP的时候,发现一些管脚根本不是我们想要功能,后来才发现两个CORTEX-M3核也在对某些寄存器配置。源码里M3-ISS对应ti_tools/iss_03_80_00_00/packages/ti/psp,M3-HDVPSS对应的是ti_tools/hdvpss_01_00_01_37/packages/ti/psp。

内核里除了上面的平台配置工作,还有很多外设的初始化工作,这里就没必要详细去写了,这些外设初始化网上都有文章参考。内核运行起来,一种以NFS文件系统方式去挂载虚拟机主机/home/davinci/dm8127/v3.8.0/Soure/ipnc_rdk/target/filesys:
图像识别DM8127开发攻略——KERNEL的移植说明_第7张图片
然后进行linux 应用程序调试。另一种是使用build_7_ubifs.sh制作ubifs文件系统的BIN文件dm8127_ubifs.bin(见本人https://blog.51cto.com/zjbintsystem/2043380文章介绍),
烧写到NAND FLASH去运行产品级的程序。

整个DM8127开发攻略到这篇就可以扎口了,本公司开发任务重点在新平台的研发,新平台是否成功,也只能放手一搏,现在的经济形势对做产品设计的实体企业非常非常不好,特别是税、人工和电子物料疯狂涨价,现在都2018年3月份了,还一直没看到降价的势头,其实最根本原因就是核动力印钞机(网友打比方)太可怕了,这种对底层民众疯狂的打劫,怎么说好呢?企业要生存,原材料就必须涨价,否则就无法给这些辛辛苦苦做事的员工增加工资,他们也要生活,什么都疯狂涨价,连锁反应。而另一方面,虚拟的产品、金融传销,普天盖地鼓吹,目的就是找韭菜接盘。还有就是打着技术的口号,疯狂欺骗融资,象AI,到现在还没有一个很好的嵌入式平台能够在不同环境下准确(100%)的快速的去识别人脸,特征行为,车牌等等。因为源头的嵌入式芯片功耗和性能就摆在那里,欺骗不了我们。不过AI的热度又快到头了,AI这两年飞在天上的猪,很快又被另外一个区块链(在中国就是一种变种金融传销,肯定会变种的)取代。其实这些实体经济萧条和乱象还没有另外一种现象更让人担忧,科技的进步和觉醒的国人不知是否能防止这种现象再一次重演。