linux内核(二)内核移植(DM365-DM368开发攻略——linux-2.6.32的移植)
一、介绍linux-2.6.32:
- 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/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
第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命令,这样就看到熟悉的内核配置界面。
图-11
图-12
四、分析和修改代码:
1、mach-davinci\board-dm365-evm.c
static struct mtd_partition davinci_nand_partitions[] = {
{
/* UBL (a few copies) plus U-Boot */
.name = "bootloader",
.offset = 0x80000,
.size = * NAND_BLOCK_SIZE,
.mask_flags =,
/* tongye:.mask_flags = MTD_WRITEABLE, *//* force read-only */
}, {
/* U-Boot environment */
.name = "params",
.offset = 0xe0000,
.size = * NAND_BLOCK_SIZE,
.mask_flags = ,
}, {
.name = "kernel",
.offset = 0x100000,
.size = SZ_4M+SZ_512K,
.mask_flags = ,
}, {
.name = "basefs",
.offset = 0x100000+SZ_4M+SZ_512K,
.size = SZ_32M-SZ_4M,
.mask_flags = ,
/* tongye:28M-byte for ramdisk,cramfs,squashfs rootfs*/
}, {
.name = "userfs",
.offset = 0x100000+SZ_32M+SZ_512K,
.size = SZ_64M+SZ_16M,
.mask_flags = ,
/*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 = ,
}
/* 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() | BIT() | BIT() | BIT();
__raw_writeb(val, (cpld + CPLD_POWER));
val = __raw_readb(cpld + CPLD_MUX) | BIT() | BIT() | BIT() | BIT();
__raw_writeb(val, (cpld + CPLD_MUX));
/* Reset bit6 of CPLD_IMG_DIR2 */
val = __raw_readb(cpld + CPLD_IMG_DIR2) & ~BIT();
__raw_writeb(val, (cpld + CPLD_IMG_DIR2));
/* Set bit5 of CPLD_IMG_MUX5 */
val = __raw_readb(cpld + CPLD_IMG_MUX5) | BIT();
__raw_writeb(val, (cpld + CPLD_IMG_MUX5));
/* Reset bit 0 of CPLD_IMG_MUX5 */
val = __raw_readb(cpld + CPLD_IMG_MUX5) & ~BIT();
__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(, "sensor_reset");
gpio_request(, "sensor_standby");
gpio_direction_output(, );
gpio_direction_output(, );
gpio_set_value(,);
gpio_set_value(,);
mdelay(); 头文件要加上#include <linux/delay.h>
gpio_set_value(,);
gpio_set_value(,);
mdelay();
gpio_set_value(,);
gpio_set_value(,);
mdelay(); #else
davinci_cfg_reg(DM365_GPIO40);
gpio_request(, "sensor_reset");
if (rst)
gpio_direction_output(, );
else
gpio_direction_output(, );
#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 = ,
.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 = ,
.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 *),
},
}
};
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();
label = "tvp5158 SD";
dm365evm_reset_imager();
break;
case VPFE_SUBDEV_MT9P031:
mux |= CPLD_VIDEO_INPUT_MUX_IMAGER;
resets |= BIT(); /* Put TVP5146 in reset */
label = "HD imager";
dm365evm_reset_imager();
/* Switch on pca9543a i2c switch */
////if (have_imager())
////dm365evm_enable_pca9543a(1);
break;
case VPFE_SUBDEV_TVP7002:
resets &= ~BIT();
mux |= CPLD_VIDEO_INPUT_MUX_TVP7002;
label = "tvp7002 HD";
break;
default:
return ;
}
////__raw_writeb(mux, cpld + CPLD_MUX);
////__raw_writeb(resets, cpld + CPLD_RESETS);
pr_info("EVM: switch to %s video input\n", label);
return ;
}
上面的函数去掉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(, 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 = ;
/* 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()) == ) {
/* external keypad mux */
mux |= BIT();
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() | BIT() | BIT() | BIT();
/* ... 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();
/* ... and AIC33 */
resets &= ~BIT();
/* 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();
dm365evm_reset_imager();
} else {
/* we can use MMC1 ... */
dm365evm_mmc_configure();
davinci_setup_mmc(, &dm365evm_mmc_config);
if (have_tvp7002()) {
mux |= CPLD_VIDEO_INPUT_MUX_TVP7002;
resets &= ~BIT();
label = "tvp7002 HD";
} else {
/* default to tvp5146 */
mux |= CPLD_VIDEO_INPUT_MUX_TVP5146;
resets &= ~BIT();
label = "tvp5158 SD";
dm365evm_reset_imager();
}
}
__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();
//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 */
}
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(, &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
大部分转自:https://blog.csdn.net/kylin_fire_zeng/article/details/42082343
linux内核(二)内核移植(DM365-DM368开发攻略——linux-2.6.32的移植)的更多相关文章
- Davinci DM6446开发攻略——LINUX GPIO驱动源码移植
一. DM6446 GPIO的介绍 说到LINUX 驱动移植,没有移植过的朋友,或刚刚进入LINUX领域的朋友,最好去看看<LINUX 设备驱动程序>第三 ...
- TI Davinci DM6446开发攻略——根文件系统的裁剪和移植
一.补充文件系统知识 Linux根文件系统是存放tool软件.lib文件.script(脚本).配置文件.其他特殊文件.自己开发的应用程序的地方.嵌入式linux的根文件系统rootfs就像windo ...
- Davinci DM6446开发攻略——linux-2.6.18移植
TI DAVINCI 使用最新的内核是montavista linux-2.6.18,之前说过,国内很多公司,包括开发板的软件包,一直在使用montavista linux-2.6.10,这个版本准 ...
- Davinci DM6446开发攻略——u-boot-1.3.4移植(1)
UBOOT的版本更新速度比较快,截止今天,稳定正式的版本是u-boot-2009.11-rc2,而TI最新的EVM开发包里的UBOOT是1.2.0版本,国内很多公司还一直使用u-boot-1.1.4和 ...
- DM6446开发攻略——u-boot-1.3.4移植(1)
http://zjbintsystem.blog.51cto.com/964211/282387转载 UBOOT的版本更新速度比较快,截止今天,稳定正式的版本是u-boot-2009.11-rc2 ...
- Davinci DM6446开发攻略-UBOOT-2009.03移植2 nand flash的烧写
很长一段时间没有更新博客了,是因为要推出新开发方案和做好客户服务工作,忙得不易乐乎.有关DAVINCI U-BOOT的移植,以前写过一篇u-boot-1.3.4(2008年的),其实和这个u-bo ...
- TI Davinci DM6446开发攻略——开发环境搭建
TI DAVINCI DM6446的开发环境搭建不像三星S3C2410,S3C2440,ATMEL的AT91SAM9260之类的单核ARM那么简单,因为DM6446还有DSP端的开发环境,以及双核之间 ...
- Davinci DM6446开发攻略——DSP开发工程建立
前段时间一直忙一个项目,同时在生活上时时提防和抵抗中国地沟油.国外核心转基因调和油.大豆油.色拉油.大米玉米.可怕的喂药鱼.药水泡农药喷无虫咬的青菜,所以没时间打理自己的博客,让开发攻略停顿了一段时间 ...
- DAVINCI DM6446 开发攻略——V4L2视频驱动和应用分析
针对DAVINCI DM6446平台,网络上也有很多网友写了V4L2的驱动,但只是解析Montavista linux-2.6.10 V4L2的原理.结构和函数,深度不够.本文决定把Montavis ...
随机推荐
- V$INSTANCE 字段说明
http://blog.csdn.net/wyzxg/article/details/4728622 http://blog.csdn.net/warden2010/article/details/6 ...
- CSU 1541 There is No Alternative (最小生成树+枚举)
题目链接:传送门 题意: 有n个点.m条边.要使n个点所有连起来且要花费最小.问有哪些边是必需要连的. 分析: 要使花费最小肯定是做最小生成树.可是题目要求哪些边是必需要用的.我们能够 这样思考,我们 ...
- 嵌入式linux和pc机的linux对照
linux本身具备的非常大长处就是稳定,内核精悍,执行时须要的资源少.嵌入式linux和普通linux并无本质差别. 在嵌入式系统上执行linux的一个缺点就是其核心架构没有又一次设计过,而是直接从桌 ...
- 【Java并发编程实战】—–synchronized
在我们的实际应用其中可能常常会遇到这样一个场景:多个线程读或者.写相同的数据,訪问相同的文件等等.对于这样的情况假设我们不加以控制,是非常easy导致错误的. 在java中,为了解决问题,引入临界区概 ...
- 深入分析JavaWeb Item39 -- 监听器(Listener)学习进阶
一.监听域对象中属性的变更的监听器 域对象中属性的变更的事件监听器就是用来监听 ServletContext, HttpSession, HttpServletRequest 这三个对象中的属性变更信 ...
- JAVA项目中公布WebService服务——简单实例
1.在Java项目中公布一个WebService服务: 怎样公布? --JDK1.6中JAX-WS规范定义了怎样公布一个WebService服务. (1)用jdk1.6.0_21以后的版本号公布. ( ...
- PBKDF2加密的实现
PBKDF2(Password-Based Key Derivation Function). 通过哈希算法进行加密.由于哈希算法是单向的,能够将不论什么大小的数据转化为定长的"指纹&quo ...
- 读取excel模板填充数据 并合并相同文本单元格
try { string OutFileName = "北京市国控企业污染源废气在线比对监测数据审核表" + DateTime.Now.ToString(& ...
- nyoj--118--修路方案(次小生成树)
修路方案 时间限制:3000 ms | 内存限制:65535 KB 难度:5 描述 南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利,南将军准备修路. ...
- 【POJ 1082】 Calendar Game
[题目链接] http://poj.org/problem?id=1082 [算法] 对于每种状态,要么必胜,要么必败 记忆化搜索即可 [代码] #include <algorithm> ...