linux內核(二)內核移植(DM365-DM368開發攻略——linux-2.6.32的移植)


一、介紹linux-2.6.32:

  Linux-2.6.32的網上介紹:增添了虛擬化內存 de-duplicacion、重寫了 writeback 代碼、改進了 Btrfs 文件系統、添加了 ATI R600/R700 3D 和 KMS 支持、CFQ 低傳輸延遲時間模式、perf timechart 工具、內存控制器支持 soft limits、支持 S+Core 架構、支持 Intel Moorestown 及其新的固件接口、支持運行時電源管理、以及新的驅動;這些本人不懂,但是本人只注意到常用的LINUX操作系統RADHAT Enterprise 6,ubuntu-10.04,debian 6.0穩定版本,這些都是使用linux-2.6.32這個版本,智能手機就更多了,android手機(經典版本HTC-G7手機使用linux-2.6.32.15和android 2.2版本結合),因為只有從linux-2.6.32以后,才能發揮android系統的優勢;不過單核的DM368無論是432MHz還是新出的500多MHz,跑android系統非常困難,只能跑QT,這里不討論;
  先從dvsdk_dm368_4_02_00_06\下的Rules.make和Makefile開始
  • Rules.make第45行,LINUXKERNEL_INSTALL_DIR=$(DVSDK_INSTALL_DIR)/psp/linux-2.6.32.17,很明顯我們把內核名字改成linux-2.6.32.17,原來解壓安裝出來的名字太長了,所以要在Rules.make第45行改一下;
  • Makefile是編譯的腳本,TI把整個DVSDK4.02的開發環境統一整合在一起,體現在這個Makefile,看完這個Makefile,就應該知道如何編譯整個DVSDK里所有的軟件包,內核編譯的命令見143行開始;
  • 在dvsdk_dm368_4_02_00_06\目錄下使用make linux,make linux_config, make linux_clean等命令編譯內核;

二、開始移植:從刪除多余的文件夾和文件開始

先看刪除前后的源碼大小對比,當然還有些可以接着刪。

1,進入文件夾linux-2.6.32.17-psp03.01.01.39\arch\arm\configs,只保留davinci_dm365_defconfig。

2,刪除非ARM芯片平台的處理器

  進入dvsdk_dm368_4_02_00_06/psp/linux-2.6.32.17/arch,保留arm,um,x86三個文件夾,其他文件刪除掉;

  

  進入dvsdk_dm368_4_02_00_06/psp/linux-2.6.32.17/arch/um文件夾,只保留scripts文件夾,其他刪除掉,包括那幾個文件Kconfig等文件也刪除掉;
  

  進入dvsdk_dm368_4_02_00_06/psp/linux-2.6.32.17/arch/x86文件夾,只保留include和mm文件夾,和幾個文件,其他文件夾刪除掉

   

  dvsdk_dm368_4_02_00_06/psp/linux-2.6.32.17/arch/arm文件夾,保留mach-davinci文件夾和保留下圖的文件夾和文件,其他帶mach-刪除吧,占空間,又占備份時壓縮的時間,

   

3、修改dvsdk_dm368_4_02_00_06/psp/linux-2.6.32.17/arch/arm/Makefile

從第120行開始,#machine-$(CONFIG_ARCH_AAEC2000)         := aaec2000
一直到172行,#machine-$(CONFIG_ARCH_MXC91231)         := mxc91231
只保留machine-$(CONFIG_ARCH_DAVINCI)        := davinci,其他全部使用”#”給屏蔽掉

第176行到第184統統使用”#”給屏蔽掉,不要這些芯片平台;

4、修改dvsdk_dm368_4_02_00_06/psp/linux-2.6.32.17/arch/arm/Kconfig

從第707行開始,一直到793行,這些全部使用“#”給屏蔽掉,保留第795行的source "arch/arm/mach-davinci/Kconfig";

然后繼續把第797到805行使用“#”給屏蔽掉;

經過上面的刪除,使用tar jcf 或 tar zcf壓縮的linux-2.6.32.17降到51M,比沒有刪除的減小近一半的大小;我們追求簡潔,思路清晰;其實還有很多地方可以刪除的,大家慢慢體會,包括include,driver里邊的老掉牙的設備,這里就不啰嗦了;刪除后記得把對應的Kconfig和Makefile給屏蔽掉;

三、開始從內核配置

使用make linux_config命令,這樣就看到熟悉的內核配置界面。

圖-5
我們按順序一個一個配置,當然,很多配置選項都是使用TI davinci_dm365_defconfig配置好的,我們對它們進行分析、裁剪、修改,
進入“General setup”配置
圖-6
上圖是我們多選了RAM disk文件系統支持的壓縮方式,默認是使用gzip生產RAM DISK文件系統,你也可以使用bzip2和LZMA(壓縮率比前面兩個高);

 

圖-7
進入“System Type”配置,上面按TI 原來的配置,

 

圖-8
然后直接進入“TI Davinci Implementations”,按上面的選擇,最后面的27000000表示你的主芯片晶振是27MHz還是24MHz,本公司的是24MHz晶振,我們就把27000000改成24000000;
圖-9
返回圖-5,進入“Networking support”,你的系統如果沒有WIFI等無線模塊,這個無線的“wireless”協議可以不選;
 
圖-10
主要對“Networking options”進行配置,這里基本上就是IPV4和IPV6的協議配置,我們按TI原來的選擇,帶“M”選項也可以使用“*”編譯進內核,而不是模塊;

                          圖-11

 

              圖-12

返回圖-5進入“Device Drivers”,這是配置內核的重點,見圖-11和圖-12,
 
圖-13
按順序先對NAND FLASH分區MTD進行配置,直接參考TI 默認的配置;

 

圖-14
圖-14 RAM/ROM/FLASH及下面3個使用TI默認的配置,
圖-15
進入“NAND device Support”的配置,一定要選擇“Support NAND on Davinci SoC”,
圖-16
這是2.6.32新的特性,開始支持UBI文件系統,UBI文件系統的出現,可以讓JFFS2,YAFFS2退出市場,跑android系統,必須用到,這里我們可以不選,也可以選,根據你的板子要使用什么樣的文件系統;
                圖-17
返回圖-11進入“Block devices”配置,我們直接使用TI的配置,

圖-18
返回圖-11進入“SCSI device support”的配置,選擇這個來支持U盤,否則你的U盤無法被DM368板子識別,我們一般把DM368 USB設置HOST模式;

 

圖-19
返回圖-11進入“Network device support”的配置,一般的RJ45網口選擇“10M or 100Mbit”,DM368不支持1000Mbit,無線“Wireless LAN”你不需要的話可以不選;“PPP”這個可以不選,而有時要支持3G的模塊的時候,PPP協議(見圖-10的配置)和設備支持要選擇;
 
圖-20
進入“10M or 100Mbit”,選擇“TI Davinci EMAC Support;

圖-21
返回圖-11進入“Input device support”,這選擇是否支持鼠標鍵盤觸摸屏等輸入,我們這邊用不上,直接不選;
圖-22
返回圖-11進入“Char device”,一定要選擇DM365 IPIPE,IMP Previewer,IMP Resizer,這個到時候調試視頻采集程序需要用到Previewer、Resizer等DAVINCI技術;

圖-23
在圖-22中,選擇進入“Serial driver”,這里就是DM368的串口配置了,DM368支持UART0 和UART1,UART1和其他GPIO復用,小心分配使用硬件資源,和DM6446一樣,都是8250的驅動,而DM6446可以配置3個UART;

 

圖-24
返回圖-11進入“I2C Support”,這個沒得說,肯定使用選上的,
圖-25
 
TI開發板使用的I2C擴展芯片,我們不需要,所以External就不要了,只選上“Davinci I2C driver”;

圖-26
返回圖-11進入“SPI Support”,如果你的板子沒有外接SPI接口的芯片,這里可以不選;
圖-27
返回圖-11進入“GPIO Support”,TI使用芯片擴展更多的GPIO腳,我們不需要,可以不選;
圖-28
返回圖-11進入“Watchdog Timer Support”,凡是使用軟件看門狗的,都需要選上這個,DM368和DM6446這些芯片都支持軟件看門狗,注意選擇是“Davinci watchdog”;
圖-29
返回圖-11進入 “Multimedia support”,多媒體支持,這個就是Davinci的重點,
圖-30
按TI默認的選擇,MT9P031 500萬像素的SERSEOR可以選上,你有其他公司的SENSOR,也可以參考MT9P031的方法加入你SENSOR的驅動,然后修改linux-2.6.32.17\drivers\media\video里邊的Makefile和Kconfig文件就OK了;
圖-31
然后從圖-30的“encoders/decoders and xxxx”進去選擇TVP5146,高清Ypbpr輸出THS7303,TH7353芯片的選擇支持,我們公司使用TVP5158,本人把它加入內核編譯,所以這里顯示TVP5158,TVP7002我們沒有使用,所以不用選;
 
圖-32
返回圖-11進入“Graphics Suppor”,這個就是選擇支持TFT3.5, TFT4.3寸LCD屏的驅動,也就是通過RGB接口支持屏的輸出,我板子不支持,可以選擇也可以按TI默認的設置;
圖-33
返回圖-11進入“Sound card Suppor”,聲卡選擇,
圖-34
DM368主芯片上帶有音頻功能的模塊,直接按TI的設置,

 

圖-35
返回圖-11進入“USB Suppor”,我們把DM368跑的LINUX系統當作HOST來使用,“HID Support”是支持鼠標鍵盤之類的東西,可以選也可以不要;基本上采用TI的默認配置
圖-36
這里選擇支持U盤,這個和前面說過的SCSI Spport是對應的;
圖-37
返回圖-11進入“MMC/SD/SDIO Suppor”,linux-2.6.32的SD卡驅動完全支持32G的容量,DM368支持兩個SD卡接口0和1,使用SD0基本不需要什么移植,使用SD1內核驅動注意使用SD1卡時,復用的GPIO腳就不需要了;
圖-38
返回圖-11進入“Real Time Clock”,DM368支持片上的RTC時鍾,即“TI Davinci RTC”,我們自己的板子支持外部RTC時鍾芯片PCF8563,根據外設選擇;

圖-39
返回圖-5進入“File systems”,對需要支持的文件系統進行選擇,選擇EXT2/EXT3/EXT4文件系統是在斷電對存儲設備保護和日志恢復的情況下,比FAT32好多了,比如把SD卡格式化成EXT3/EXT4比FAT32更好用;

圖-40
其他保留TI的配置,

圖-41
進入“DOS/FAT/NT”文件系統的支持,按上面的選擇,NTFS沒有用過,不知在嵌入式是否好用,這里選擇的目的是能夠使用U盤等等存儲設備;

圖-42
進入“Pseudo filesystems”,保留TI的默認配置;

圖-43

圖-44
進入“Miscellaneous filesystems”,配置NAND FLASH支持的文件系統,YAFFS2的文件系統是本人下載然后按patch就行移植的,TI原來沒有,選擇YAFF2,JFFS2,還有cramfs,SquashFS,UBI文件系統目前沒有驗證,有時間再試試,剛才提到的都是最常用的嵌入式NAND文件系統,就是要燒進NAND FLASH的;

圖-45
圖-45就是NFS文件系統的設置,我們在板子上運行的是NFS client模式,即客戶端,而開發環境是NFS SERVER端;里邊的SMB(SAMBA)在板子上不需要支持,我們去掉不選;

 
圖-46
圖-46就是選擇內核支持的語言;
 
然后備份配置:在dvsdk_dm368_4_02_00_06目錄下
#cp psp/linux-2.6.32.17/.config  psp/linux-2.6.32.17/dm368_20111227.config
注意路徑,凡是使用make distclean和make linux_clean命令后,.config不存在,這時我們就必須使用:
#cp psp/linux-2.6.32.17/dm368_20111227.config psp/linux-2.6.32.17/.config注意.config的“.”,這樣整個內核配置基本結束;

 四、分析和修改代碼:

1、mach-davinci\board-dm365-evm.c

這個是DM368內核移植重點的地方,系統初始化函數都在這里,而外部設備初始化在各自的驅動文件里;
打開第156行 #define NAND_BLOCK_SIZE            SZ_128K
同時屏蔽/*#define NAND_BLOCK_SIZE         SZ_512K*/ 這個是4K-PAGE NAND FLASH
因為我們公司的板子都是使用2K-PAGE的NAND FLASH,512字節的NAND不適合新的文件系統,慢慢會被淘汰;
修改NAND FLASH的分區:
static struct mtd_partition davinci_nand_partitions[] = {
       {
              /* UBL (a few copies) plus U-Boot */
              .name             = "bootloader",
              .offset            = 0x80000,
              .size        = 3 * NAND_BLOCK_SIZE,
              .mask_flags    =0,
              /* tongye:.mask_flags    = MTD_WRITEABLE, *//* force read-only */
       }, {
              /* U-Boot environment */
              .name             = "params",
              .offset            = 0xe0000,
              .size        = 1 * NAND_BLOCK_SIZE,
              .mask_flags    = 0,
       }, {
              .name             = "kernel",
              .offset            = 0x100000,
              .size        = SZ_4M+SZ_512K,
              .mask_flags    = 0,
       }, {
              .name             = "basefs",
              .offset            = 0x100000+SZ_4M+SZ_512K,
              .size        = SZ_32M-SZ_4M,
              .mask_flags    = 0,
              /* tongye:28M-byte for ramdisk,cramfs,squashfs rootfs*/
       }, {
              .name             = "userfs",
              .offset            = 0x100000+SZ_32M+SZ_512K,
              .size        = SZ_64M+SZ_16M,
              .mask_flags    = 0,
              /*tongye:80M-byte for jffs2,yaffs2 rootfs*/
       }, {
              .name             = "userdata",
              .offset            = SZ_64M+SZ_32M+SZ_16M+SZ_1M+SZ_512K,
              .size        = 0x8000000-SZ_64M-SZ_32M-SZ_16M-SZ_1M-SZ_512K,
              .mask_flags    = 0,
       }
       /* two blocks with bad block table (and mirror) at the end */
};

UBL的代碼放在0x20000~0x40000的位置,一般NAND FLASH前面5個BLOCK出現壞塊的幾率非常小,在產品中一般很少去維護更新UBL,所以沒有把UBL單獨分一個分區;而其他空間出現壞塊的幾率比較大,所以給U-BOOT分3~4個BLOCK夠用了,內核分5M-BYTE也夠用,而U-BOOT參數分1~2個BLOCK,本公司直接放到0x60000~0x80000的空間也可以,沒有規定;后面的文件系統分區就根據你裁剪的文件系統、文件系統的類型進行大小分區;

static struct i2c_board_info i2c_info[] = {
/*    {
              I2C_BOARD_INFO("dm365evm_keys", 0x25),
       },
       {
              I2C_BOARD_INFO("24c256", 0x50),
              .platform_data       = &eeprom_info,
       },
*/
       {
              I2C_BOARD_INFO("tlv320aic3x", 0x18),
       },
       {
              I2C_BOARD_INFO("ths7303", 0x2c),
       },
       /*{
              I2C_BOARD_INFO("PCA9543A", 0x73),
       },*/
       {
              I2C_BOARD_INFO("pcf8563", 0x51),
       },
};

上面這個結構就是看看你的I2C總線帶什么樣的設備,根據你的I2C設備地址,添加到這里,這樣才能調用到設備初始化函數;從上面的修改看出,我們的板子不需要AT24C256這些EEPROM芯片,可以干掉;

static void dm365evm_reset_imager(int rst)
{
       u8 val;
//tongye
#if 0      
   val = __raw_readb(cpld + CPLD_POWER) | BIT(3) | BIT(11) | BIT(19) | BIT(27);
       __raw_writeb(val, (cpld + CPLD_POWER));
   val = __raw_readb(cpld + CPLD_MUX) | BIT(6) | BIT(14) | BIT(22) | BIT(30);
       __raw_writeb(val, (cpld + CPLD_MUX));
       /* Reset bit6 of CPLD_IMG_DIR2 */
       val = __raw_readb(cpld + CPLD_IMG_DIR2) & ~BIT(6);
       __raw_writeb(val, (cpld + CPLD_IMG_DIR2));
       /* Set bit5 of CPLD_IMG_MUX5 */
       val = __raw_readb(cpld + CPLD_IMG_MUX5) | BIT(5);
       __raw_writeb(val, (cpld + CPLD_IMG_MUX5));      
       /* Reset bit 0 of CPLD_IMG_MUX5 */
       val = __raw_readb(cpld + CPLD_IMG_MUX5) & ~BIT(0);
       __raw_writeb(val, (cpld + CPLD_IMG_MUX5));      
#endif
       /**
        * Configure GPIO40 to be output and high. This has dependency on MMC1
        */
#if 1
       davinci_cfg_reg(DM365_PWM3_G85);
       davinci_cfg_reg(DM365_PWM3_G86);
       gpio_request(85, "sensor_reset");
       gpio_request(86, "sensor_standby");
       gpio_direction_output(85, 0);
       gpio_direction_output(86, 0);
       gpio_set_value(85,1);
       gpio_set_value(86,1);
       mdelay(15); 頭文件要加上#include <linux/delay.h>
       gpio_set_value(85,0);
       gpio_set_value(86,0);
       mdelay(25);
       gpio_set_value(85,1);
       gpio_set_value(86,1);
       mdelay(25);
      
#else
       davinci_cfg_reg(DM365_GPIO40);
       gpio_request(40, "sensor_reset");
       if (rst)
              gpio_direction_output(40, 1);
       else
              gpio_direction_output(40, 0);
#endif
}

上面的函數修改:我們不需要CPLD,所以屏蔽掉,我們直接使用GPIO控制MT9P031 SENSOR的復位和STANDBY信號;

static struct vpfe_subdev_info vpfe_sub_devs[] = {
       {
              .module_name = "tvp5158",
              .grp_id = VPFE_SUBDEV_TVP5146,
              .num_inputs = ARRAY_SIZE(tvp5158_inputs),
              .inputs = tvp5158_inputs,
              .routes = tvp5158_routes,
              .can_route = 1,
              .ccdc_if_params = {
                     .if_type = VPFE_BT656,
                     .hdpol = VPFE_PINPOL_POSITIVE,
                     .vdpol = VPFE_PINPOL_POSITIVE,
              },
              .board_info = {
                     I2C_BOARD_INFO("tvp5158", 0x5B),
                     .platform_data = &tvp5158_pdata,
              },
       },
       {
              .module_name = "tvp7002",
              .grp_id = VPFE_SUBDEV_TVP7002,
              .num_inputs = ARRAY_SIZE(tvp7002_inputs),
              .inputs = tvp7002_inputs,
              .ccdc_if_params = {
                     .if_type = VPFE_BT1120,
                     .hdpol = VPFE_PINPOL_POSITIVE,
                     .vdpol = VPFE_PINPOL_POSITIVE,
              },
              .board_info = {
                     I2C_BOARD_INFO("tvp7002", 0x5c),
                     .platform_data = &tvp7002_pdata,
              },
       },
       {
              .module_name = "ths7353",
              .grp_id = VPFE_SUBDEV_TVP7002,
              .board_info = {
                     I2C_BOARD_INFO("ths7353", 0x2e),
              },
       },
       {
              .module_name = "mt9p031",
              .is_camera = 1,
              .grp_id = VPFE_SUBDEV_MT9P031,
              .num_inputs = ARRAY_SIZE(mt9p031_inputs),
              .inputs = mt9p031_inputs,
              .ccdc_if_params = {
                     .if_type = VPFE_RAW_BAYER,
                     .hdpol = VPFE_PINPOL_POSITIVE,
                     .vdpol = VPFE_PINPOL_POSITIVE,
              },
              .board_info = {
                     I2C_BOARD_INFO("mt9p031", 0x48),
                     /* this is for PCLK rising edge */
                     .platform_data = (void *)1,
              },
       }
};

TI的DM368開發板同時支持TVP5146、TVP7002、MT9P031;TVP5146代表標清復合視頻輸入采集芯片(D1格式),TVP7002代表復合視頻YPbPr的高清輸入采集芯片,MT9P031代表500萬像素的SENSOR采集;

/* Set the input mux for TVP7002/TVP5146/MTxxxx sensors */
static int dm365evm_setup_video_input(enum vpfe_subdev_id id)
{
       const char *label;
       u8 mux, resets;
//Jingbo
       /////mux = __raw_readb(cpld + CPLD_MUX);
       ////mux &= ~CPLD_VIDEO_INPUT_MUX_MASK;
       ////resets = __raw_readb(cpld + CPLD_RESETS);
       switch (id) {
              case VPFE_SUBDEV_TVP5146:
                     mux |= CPLD_VIDEO_INPUT_MUX_TVP5146;
                     resets &= ~BIT(0);
                     label = "tvp5158 SD";
                     dm365evm_reset_imager(0);
                     break;
              case VPFE_SUBDEV_MT9P031:
                     mux |= CPLD_VIDEO_INPUT_MUX_IMAGER;
                     resets |= BIT(0); /* Put TVP5146 in reset */
                     label = "HD imager";
                     dm365evm_reset_imager(1);
                     /* Switch on pca9543a i2c switch */
                     ////if (have_imager())
                            ////dm365evm_enable_pca9543a(1);
                     break;
              case VPFE_SUBDEV_TVP7002:
                     resets &= ~BIT(2);
                     mux |= CPLD_VIDEO_INPUT_MUX_TVP7002;
                     label = "tvp7002 HD";
                     break;
              default:
                     return 0;
       }
       ////__raw_writeb(mux, cpld + CPLD_MUX);
       ////__raw_writeb(resets, cpld + CPLD_RESETS);
       pr_info("EVM: switch to %s video input\n", label);
       return 0;
}

上面的函數去掉CPLD的東西,這個視頻采集芯片的選擇是和U-BOOT的參數一一對應的,在U-BOOT bootargs的參數里,加入davinci_capture.device_type=0表示使用TVP5146采集,davinci_capture.device_type=1表示使用MT9P031采集,davinci_capture.device_type=2表示使用TVP7002采集,內核讀取U-BOOT的參數,會在初始化確定是否調用什么樣的采集芯片驅動;所以我們在內核配置的時候,可以同時選上三種芯片;

static void __init evm_init_i2c(void)
{
       davinci_init_i2c(&i2c_pdata);
#if 0
       if (have_imager())
              i2c_add_driver(&pca9543a_driver);
#endif
       i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
}

這個pca9543a I2C切換芯片我們不需要;

static void __init evm_init_cpld(void)
{
       u8 mux, resets;
       const char *label;
       struct clk *aemif_clk;
       struct davinci_soc_info *soc_info = &davinci_soc_info;
       /* Make sure we can configure the CPLD through CS1. Then
        * leave it on for later access to MMC and LED registers.
        */
       aemif_clk = clk_get(NULL, "aemif");
       if (IS_ERR(aemif_clk))
              return;
       clk_enable(aemif_clk);
#if 0
       if (request_mem_region(DM365_ASYNC_EMIF_DATA_CE1_BASE, SECTION_SIZE,
                     "cpld") == NULL)
              goto fail;
       cpld = ioremap(DM365_ASYNC_EMIF_DATA_CE1_BASE, SECTION_SIZE);
       if (!cpld) {
              release_mem_region(DM365_ASYNC_EMIF_DATA_CE1_BASE,
                            SECTION_SIZE);
fail:
              pr_err("ERROR: can't map CPLD\n");
              clk_disable(aemif_clk);
              return;
       }
       /* External muxing for some signals */
       mux = 0;
       /* Read CPLD version number */
       soc_info->cpld_version = __raw_readb(cpld + CPLD_VERSION);
       /* Read SW5 to set up NAND + keypad _or_ OneNAND (sync read).
        * NOTE: SW4 bus width setting must match!
        */
       if ((__raw_readb(cpld + CPLD_SWITCH) & BIT(5)) == 0) {
              /* external keypad mux */
              mux |= BIT(7);
              platform_add_devices(dm365_evm_nand_devices,
                            ARRAY_SIZE(dm365_evm_nand_devices));
       } else {
              /* no OneNAND support yet */
       }
       /* Leave external chips in reset when unused. */
       resets = BIT(3) | BIT(2) | BIT(1) | BIT(0);
       /* ... and ENET ... */
       dm365evm_emac_configure();
       soc_info->emac_pdata->phy_mask = DM365_EVM_PHY_MASK;
       soc_info->emac_pdata->mdio_max_freq = DM365_EVM_MDIO_FREQUENCY;
       resets &= ~BIT(3);
       /* ... and AIC33 */
       resets &= ~BIT(1);
       /* Static video input config with SN74CBT16214 1-of-3 mux:
        * - port b1 == tvp7002 (mux lowbits == 1 or 6)
        * - port b2 == imager (mux lowbits == 2 or 7)
        * - port b3 == tvp5146 (mux lowbits == 5)
        *
        * Runtime switching could work too, with limitations.
        */
       if (have_imager()) {
              label = "HD imager";
              mux |= CPLD_VIDEO_INPUT_MUX_IMAGER;
              /* externally mux MMC1 to imager */
              mux |= BIT(6);
              dm365evm_reset_imager(1);
       } else {
              /* we can use MMC1 ... */
              dm365evm_mmc_configure();
              davinci_setup_mmc(1, &dm365evm_mmc_config);
              if (have_tvp7002()) {
                     mux |= CPLD_VIDEO_INPUT_MUX_TVP7002;
                     resets &= ~BIT(2);
                     label = "tvp7002 HD";
              } else {
                     /* default to tvp5146 */
                     mux |= CPLD_VIDEO_INPUT_MUX_TVP5146;
                     resets &= ~BIT(0);
                     label = "tvp5158 SD";
                     dm365evm_reset_imager(0);
              }
       }
       __raw_writeb(mux, cpld + CPLD_MUX);
       __raw_writeb(resets, cpld + CPLD_RESETS);
#else
       platform_add_devices(dm365_evm_nand_devices,
              ARRAY_SIZE(dm365_evm_nand_devices));
       /* ... and ENET ... */
       dm365evm_emac_configure();
       soc_info->emac_pdata->phy_mask = DM365_EVM_PHY_MASK;
       soc_info->emac_pdata->mdio_max_freq = DM365_EVM_MDIO_FREQUENCY;
       //if (have_imager())
       {
              dm365evm_reset_imager(1);
              //pr_info("EVM: reset mt9p031 imager\n");
       }
       //pr_info("EVM: %s video input\n", label);
#endif
       /* REVISIT export switches: NTSC/PAL (SW5.6), EXTRA1 (SW5.2), etc */
}
上面的函數很重要,除去掉CPLD的東西外,一定要把
       platform_add_devices(dm365_evm_nand_devices,
              ARRAY_SIZE(dm365_evm_nand_devices));
保留,否則你的內核啟動的時候,根本沒有NAND的驅動和分區顯示;
dm365evm_emac_configure();也肯定要的,否則沒有網絡驅動叫LINUX嗎?TI就是通過CPLD來控制一些外設,CPLD比較貴,不適合低成本大批量生產,所以我們去掉了;
static __init void dm365_evm_init(void)
{
       dm365evm_gpio_configure(); //tongye:copy it here
       evm_init_i2c();
       davinci_serial_init(&uart_config);
       dm365evm_emac_configure();
       dm365evm_usb_configure();
       davinci_setup_mmc(0, &dm365evm_mmc_config);
       /* maybe setup mmc1/etc ... _after_ mmc0 */
       evm_init_cpld();
       dm365_init_asp(&dm365_evm_snd_data);
       //dm365_init_rtc();
       //dm365_init_ks(&dm365evm_ks_data);
//dm365_init_spi0(BIT(0), dm365_evm_spi_info,
                     //ARRAY_SIZE(dm365_evm_spi_info));
       //dm365_init_tsc2004();
       dm365evm_gpio_configure();
}

這個函數就是對MMC/SD、USB、等接口進行初始化了,tsc2004這個是觸摸屏的芯片,dm365evm_gpio_configure()里邊我們添加了很多GPIO的初始值定義;

2、修改mach-davinci\dm365.c

這個要和arch\arm\mach-davinci\include\mach\mux.h配合看,
好好看看mux_config dm365_pins這個定義,這個DM368的管腳復用非常復雜,使能某個功能,那么對應的另外的功能就不能用了,因此要非常小心對待,特別是和GPIO復用;
 
后面這些源碼介紹就是提示和分析了:
drivers\char\里有dm365_ipipe.c
、imp_common.c、imp_previewer.c、imp_resizer.c、等文件;
 
drivers\i2c\busses\里有i2c-davinci.c
 
重點介紹:drivers\media\video\里有V4L2的接口驅動;
drivers\media\video\mt9p031.c,tvp514x.c,tvp7002.c;
 
drivers\media\video\davinci\里東西就很多了,dm365_ccdc.c、vpfe_capture.c
 
drivers\net\里有davinci_emac.c
 
drivers\usb\musb\里davinci.c
GPIO的使用,一直沒有搞清楚這個新內核為什么老是隔段時間對U盤復位,和2.6.18不一樣,搞得U盤一直成功列舉設備,然后用重新復位分配新USB DEVIDE 地址;
 
drivers\watchdog\里有davinci_wdt.c
第32行#define DEFAULT_HEARTBEAT 2    //tongye removed 60s
應用程序只有一使用open打開設備,WDG就生效,2秒鍾不喂狗就軟件復位;
 
linux-2.6.32.17\sound\soc\codecs有tlv320aicxx.c等音頻芯片驅動;
linux-2.6.32.17sound\soc\davinci里有PCM、I2S等驅動;
 
接顯示屏drivers\video\davincifb.c,這個要和drivers\media\video\davinci\的vpbe_encoder.c、davinci_display.c、davinci_osd.c啊等等VPBE接口的文件對應;
 
最后在dvsdk_dm368_4_02_00_06目錄下加個編譯腳本build_linux.sh:
 
#!/bin/sh
make linux
chmod 777 /home/davinci/dm368/dvsdk_dm368_4_02_00_06/psp/linux-2.6.32.17/arch/arm/boot/uImage
cp -f /home/davinci/dm368/dvsdk_dm368_4_02_00_06/psp/linux-2.6.32.17/arch/arm/boot/uImage /tftpboot/dm368_kernel.bin
直接./ build_linux.sh,就可以在/tftpboot的目錄下得到dm368_kernel.bin,在板子上,通過U-BOOT燒寫內核,先調試通NFS,在上篇U-BOOT的移植文章介紹到U-BOOT的NFS參數定義,這里不啰嗦;

大部分轉自:https://blog.csdn.net/kylin_fire_zeng/article/details/42082343


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM