转载自:http://zjbintsystem.blog.51cto.com/964211/284468
TI DAVINCI 使用最新的内核是montavista linux-2.6.18,之前说过,国内很多公司,包括开发板的软件包,一直在使用montavista linux-2.6.10,这个版本准确来说是比较低的,实时性肯定没2.6.18好(MontaVista Linux Professional Edition 5.0以linux-2.6.18为基础,打破了Linux不适用于实时和嵌入式应用的迷思);使用devfs,没有使用udev;对DM365等新出的DAVINCI芯片支持限度很小;ucLibc支持(减少75%应用程序资源需求);IPv6(增加更多Internet Protocol version 6 (IPv6)支持,提供比旧版产品更优异的效能、安全和管理功能);等等,这些优点不得不让人心动。
第一步:简化 linux-2.6.18 如果你已经安装好 TI mvl_5_0_0_demo_lsp_setuplinux_02_00_00_140.bin ,先在你的工作目录下建立 linux-2.6.18_pro500 的目录,进入改目录,比如 /home/<useraccount>/ dm6446/linux-2.6.18_pro500/ , COPY 内核源代码到本目录下,命令如下: cp –r /opt/mv_pro_5.0.0/montavista/pro/devkit/lsp/ti-davinci/linux-2.6.18_pro500/* . (注意 ” * ” ” . ” 之间的空格) 和 UBOOT 移植一样,我们先把一些不相关的平台给删除掉,进入 arch 目录,保留 arm 目录,其他全部删除掉。 进入 linux-2.6.18_pro500/arch/arm/ ,保留 boot , common , configs , kernel , lib , mach-davinci , mm , nwfpe , oprofile , plat-mxc , plat-omap , tools , vfp 和其他 4 个文件 Kconfig,Makefile, Kconfig-nommu, Kconfig.debug ,其他有关 mach-xxxx 的全部删除掉。 删除 include 下不相关平台的文件夹: asm-alpha , asm-arm26 , asm-cris , asm-frv , asm-h8300 , asm-i386 , asm-ia64 , asm-m32r , asm-m68k , asm-m68knommu , asm-mips , asm-parisc , asm-powerpc , asm-ppc , asm-ppc64 , asm-s390 , asm-sh , asm-sh64 , asm-sparc , asm-sparc64 , asm-um , asm-v850 , asm-x86_64 , asm-xtensa 全部删除掉,其他就不用删了,否则出问题。 第二步:建立交叉编译环境 进行下面工作之前,确保你的 GCC 已经按《 DAVINCI DM6446 开发攻略——环境搭建篇》建立好。 1、 顶层 Makefile 修改: 在 172 行,即 # make CROSS_COMPILE=ia64-linux- 下面,加入: ARCH = arm CROSS_COMPILE = arm_v5t_le- 把下面: ARCH := $(shell if [ -f .mvl_target_cpu ]; then / cat .mvl_target_cpu; / else / echo $(SUBARCH); / fi) CROSS_COMPILE = $(shell if [ -f .mvl_cross_compile ]; then / cat .mvl_cross_compile; / fi) 全部注释掉; 2、 COPY UBOOT 的 mkimage 工具 从编译好的 UBOOT 里 tool 目录下的 mkimage 工具 COPY 到 linux-2.6.18_pro500 目录以下, 3、 添加 mkzImage.sh 使用 vi 生成 mkzImage.sh ,把以下内容加入文件: #!/bin/sh ./mkimage -n 'linux-2.6.18' -A arm -O linux -T kernel -C none -a 0x80008000 -e 0x80008040 -d zImage davinci_kernel.bin chmod 777 davinci_kernel.bin cp -f davinci_kernel.bin /tftpboot 保存在 linux-2.6.18_pro500/ 目录下,配合 mkimage ,方便把 zImage 转换成 davinci_kernel.bin ,这样 UBOOT 才能把 linux kernel 给 BOOT 起来; 4、 修改 arch/arm/boot/Makefile : 在 57 行下面加入: @cp -f arch/arm/boot/zImage zImage 这样每次编译 zImage ,生成的 zImage 可以自动 COPY 到 linux-2.6.18_pro500 目录下。 5、 修改 fs/hostfs/Makefile 因为删除 um 和 asm-um ,当使用 make distclean 操作的时候会出现问题,所以把: include arch/um/scripts/Makefile.rules 注释掉。 6、 修改 arch/arm/Kconfig 因为删除其他不相关的平台的文件夹,所以 Kconfig 也把这些平台给注释掉: 从 135 行开始一直到 343 行 #config ARCH_AAEC2000 # bool "Agilent AAEC-2000 based" # select ARM_AMBA # help # This enables support for systems based on the Agilent AAEC-2000 。。。。。。。。。。。。。。。。。。。 #config ARCH_OMAP # bool "TI OMAP" # help # Support for TI's OMAP platform (OMAP1 and OMAP2). 以上全部注释掉。 从第 355 行开始到 399 行,全部注释掉: #source "arch/arm/mach-clps711x/Kconfig" #source "arch/arm/mach-ep93xx/Kconfig" 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 #source "arch/arm/mach-netx/Kconfig" 第三步:内核移植裁减 1、 在 linux-2.6.18_pro500 目录下,使用以下命令开始配置内核: cp arch/arm/configs/ davinci_dm644x_defconfig .config make menuconfig 进入熟悉的 kernel 配置界面: 2、 去掉 ATA DRIVER 由于本人的开发板没有 NOR FLASH ,也没有 ATA 硬盘之类的东西,这一点和 TI EVM 板不一样,所以我们先把设备驱动里的 ATA 选项去掉。 然后保存配置退出,使用 Make zImage 编译完后,运行 ./mkzImage.sh ,可以 COPY 生成的 bin 文件到 /tftpboot 目录下,参照上篇有关 uboot 的帖子,使板子把 uboot 运行起来,使用进入 UBOOT 命令行: U-Boot >tftp 80008000 davinci_kernel.bin U-Boot >bootm 80008000 之后可以在串口终端看到内核的运行信息。 3、 修改 arch/arm/mach-davinc/board-evm.c 有关 dm644x 的平台信息就在 board-evm.c 里,包括 nand flash 分区配置,管脚复用配置, psc 初始化等等。 在 74 行,把有关 nor flash 的代码全部注释掉,在 static struct platform_device *davinci_evm_devices[] __initdata = { &serial_device, #if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE) //&davinci_evm_flash_device, #endif #if defined(CONFIG_MTD_NAND_DAVINCI) || defined(CONFIG_MTD_NAND_DAVINCI_MODULE) &davinci_nand_device, #endif &rtc_dev, &davinci_fb_device, #if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || / defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE) &davinci_ide_device, #endif #if defined(CONFIG_MMC_DAVINCI) || defined(CONFIG_MMC_DAVINCI_MODULE) &mmc0_device, #endif }; 把 nor flash 的设备驱动注释掉; 对 nand flash 进行分区,这个要和 UBOOT 烧写 UBOOT KERNEL ROOTFS 等烧写的地址一一对应; static struct mtd_partition davinci_nand_partitions[] = { /* bootloader (U-Boot, etc) in first sector */ /*Mtdblock0*/ { .name = "bootloader", .offset = 0, .size = SZ_1M+SZ_512K, .mask_flags = 0, /* force read-only */ }, /* bootloader params in the next sector */ /*Mtdblock1*/ { .name = "dspcore", .offset = SZ_1M+SZ_512K, .size = (SZ_8M-SZ_2M-SZ_512K), .mask_flags = 0, /* force read-only */ }, ( 这里注明一下: mtdblock1 源代码被定义为 128K 参数,但是在 UBOOT 里,我们把参数放在 0x0000 开始的地址,这里可以保留该分区,也可以不要。本人定义成 DSP BIN 文件存放的地方,有种调试方式可以不用 KERNEL 就可以在 UBOOT 把 DSP BOOT 起来,双核并行运行嘛。这个分区在本人这里是拿来测试DSP程序,一般不建议使用UBOOT方式把DSP给BOOT起来。这个 DSP BIN 就是通过 HEX64 工具生成的,这和 DM642 、 DM6437 的 BIN 文件完全一样。具体说,把 DSP 程序运行起来常用有四种方法,一是硬件 BOOT 方式选择 DSP BOOT ,二是通过 UBOOT 把 BIN 启动起来,三是通过内核把 BIN 启动起来,四是 DSP SERVER 方式,即 *.x64P , 就是最常用的 Codec Engine 机制。第三种方式也有很多公司在用,然后通过共享内存方式、中断等实现双核通信。 ) /* kernel */ /*Mtdblock2*/ { .name = "kernel", .offset = (SZ_8M-SZ_1M), .size = SZ_4M+SZ_1M, .mask_flags = 0, }, /* file system */ /*Mtdblock3*/ { .name = "rootfs", .offset = (SZ_8M+SZ_4M), .size = SZ_64M, .mask_flags = 0, }, /* data */ /*Mtdblock4*/ 这个可以保存一些备份数据,一可以不用定义 { .name = "data", .offset = (SZ_64M+SZ_8M+SZ_4M), .size = (SZ_128M-(SZ_64M+SZ_8M+SZ_4M)), .mask_flags = MTD_WRITEABLE, } }; 以上是 NAND 分区信息,针对各自板子不同大小的 NAND FLASH ,合理分配空间。 #if 1 static struct platform_device rtc_dev = { .name = "pcf8563", .id = -1, }; #else static struct platform_device rtc_dev = { .name = "rtc_davinci_evm", .id = -1, }; #endif 以上的代码修改,表示板子采用 pcf8563 时钟芯片作为 RTC 设备,本人的板子不采用 TI-EVM 的电路,所以要修改这里,同时在 drivers/rtc 目录下,修改 rtc-pcf8563.c 的一个 BUG ,就是: static unsigned short normal_i2c[] = { 0x51, I2C_CLIENT_END }; 一定要加 0x51 地址,否则内核运行时,无法注册 pcf8563 的驱动,会出现 RTC 错误信息,很多网友都碰都过这个问题。改完后, make menuconfig 要选上 pcf8563 的驱动。 在 static void dm644x_setup_pinmux(unsigned int id) 里,把有关 FPGA 接口的管脚复用功能去掉,因为很多中低端 DM6446 产品都没有接 FPGA 芯片。这样我们可以把这些引脚定义成 SPI 核 UART 接口。 #if 0 case DAVINCI_LPSC_VLYNQ: davinci_cfg_reg(DM644X_VLINQEN); davinci_cfg_reg(DM644X_VLINQWD); break; #endif 同时在 arch/arm/mach-davinci/mux_cfg.c 里 struct pin_config __initdata_or_module davinci_dm644x_pins[] = { /* * description mux mode mode mux dbg * reg offset mask mode */ #if 1 //ATA 功能不用 MUX_CFG("HDIREN", 0, 16, 1, 0, 1) MUX_CFG("ATAEN", 0, 17, 1, 0, 1) #else MUX_CFG("HDIREN", 0, 16, 1, 1, 1) MUX_CFG("ATAEN", 0, 17, 1, 1, 1) #endif MUX_CFG("MSTK", 1, 9, 1, 0, 0) MUX_CFG("I2C", 1, 7, 1, 1, 0) MUX_CFG("MCBSP", 1, 10, 1, 1, 0) MUX_CFG("PWM0", 1, 4, 1, 1, 0) MUX_CFG("PWM1", 1, 5, 1, 1, 0) MUX_CFG("PWM2", 1, 6, 1, 1, 0) #if 0 MUX_CFG("VLINQEN", 0, 15, 1, 1, 0) MUX_CFG("VLINQWD", 0, 12, 3, 3, 0) #endif MUX_CFG("EMACEN", 0, 31, 1, 1, 1) MUX_CFG("GPIO3V", 0, 31, 1, 0, 1) MUX_CFG("GPIO0", 0, 24, 1, 0, 1) MUX_CFG("GPIO3", 0, 25, 1, 0, 0) MUX_CFG("GPIO43_44", 1, 7, 1, 0, 0) MUX_CFG("GPIO46_47", 0, 22, 1, 0, 1) MUX_CFG("RGB666", 0, 22, 1, 1, 1) /*MUX_CFG("RGB888", 0, 23, 1, 1, 1)*/ /* for vpbe rgb888*/ MUX_CFG("LOEEN", 0, 24, 1, 1, 1) MUX_CFG("LFLDEN", 0, 25, 1, 1, 0) }; 4、 内核进一步配置 对内核进一步配置之前,如果对 linux-2.6.18 很陌生,这里给出一个链接: http://blog.chinaunix.net/u2/71415/showart_1018029.html 一个网友对 “ Linux 2.6.19.x 内核编译配置 “进行详细的描述,不妨去看一下。 使用 cp arch/arm/configs/ davinci_dm644x_defconfig .config make menuconfig 进入内核配置界面,在这里,本人只对要修改的地方进行分析,其他设置,保留 davinci_dm644x_defconfig 。上面已经介绍有关去掉 ATA 和 TI-EVM RTC 设备,接着我们对文件系统进行裁减,如下图。图下半部没有显示,保留 davinci_dm644x_defconfig 就可以了,一般不要修改。NFS文件系统的配置也用默认的,直接编译就可以了。 其他功能和驱动,建议保留默认配置。对于自己板子新的设备(和 TI-EVM 板差别很大),则要做更复杂的移植工作,包括相应目录的 makefile 和 Kconfig 文件的修改等,这里不再累赘。 第四步:保存备份修改后的配置 内核移植配置,一定要养成备份配置文件的良好习惯,一步一个脚印,防止做重复工作。幸好 davinci_dm644x_defconfig 给大家提供一个很好的参考,否则更加麻烦。直接从内核网站下载最新内核来移植,那是非常大的挑战,不是一般人为的。 Linux-2.6.18 也许有很多设备没有支持,但在较新的 linux 内核上有,这也可以把新的驱动移植下来,这个工作量也不小,当然也有简单的 patch ,那是后话。 按照上篇UBOOT的介绍,设置好参数,比如使用NFS: mem=120M console=ttyS0,115200n8 noinitrd rw ip=dhcp root=/dev/nfs nfsroot=192.168.1.251:/home/<useraccount>/nfs/tirootfs,nolock 测试内核和NFS文件系统。 以上工作已经通过本人的板子验证,有不足的地方,大家可以博客留言共同讨论。