1
Linux-2.6.31 内核移植
手册
华为质量管理手册 下载焊接手册下载团建手册下载团建手册下载ld手册下载
2010-03-16 V1.2
手册
内容
财务内部控制制度的内容财务内部控制制度的内容人员招聘与配置的内容项目成本控制的内容消防安全演练内容
简介:
本手册是天祥电子推出的 TX-2440A 开发板的配套手册之一,全面分析了 linux
操作系统内核在嵌入式开发板上的移植过程,手册中的部分内容都会在配套的视频
教程中(第十五讲,第十六讲)进行讲解。
在开始进行移植之前,需要了解 linux 内核和驱动的相关知识,安装基本的开
发工具,搭建好开发环境;建议先看视频教程学习,在具备了一定的能力后再来参
考本手册来操作。
本手册分为 15 个部分,第 1部分,准备移植,要先掌握这一部分的操作方法,
包括(修改代码,配置内核选项,编译内核镜像,下载内核镜像到开发板,启动系
统),然后再进入后面的部分。第 2、3 部分是为挂载文件系统做准备,这里容易出
现错误(比如:文件系统不能成功挂载),可以先学习文件系统的相关知识(视频教
程第十七讲),自己制作文件系统(参考《文件系统制作手册》),在能成功挂载文件
系统后,再进入后面的部分。第 4-14 部分都是针对开发板上的硬件的驱动移植,还
介绍硬件驱动的测试方法。第 15 部分列出了驱动程序在内核源码中的位置及设备名
称,方便大家查阅。
说明:
由于个人能力有限,手册中难免会出现一些笔误和不足之处,如果发现问题,
请及时提出,目前可以发到 QQ 群上(103105892);在学习过程中遇到的问题,可以
联系我们,我们会提供技术支持。
本手册中的所有内容目前仅适用于 TX2440A 开发板,如果将其用在其他的开发
板上,出现的一切问题,我们一律不提供技术支持。
最好不要从手册中直接复制代码,因为在编写手册时,有些字符可能会自动变
成全角格式,在代码中是不允许有全角字符的,所以有可能会导致一些错误。我建
议,最好是手动编写代码。
手册中的内容会不定期的更新,以后还会加入更丰富的内容,更新后会放到 FTP
服务器供大家下载。希望广大的 TX2440A 开发板用户能多提出宝贵的意见,我会根
据大家的意见及时调整手册中的内容。
2010-3-16 相广超
哈尔滨祥鹏科技有限公司
网址:www.txmcu.com
电话:0451-87572303
2
内核版本:
Linux-2.6.31
交叉编译器版本:
arm-linux-gcc 4.1.2
操作系统平台:
Linux -- Red Hat 9.0
开发板平台:
Arm -- TX2440A
手册中字体颜色的约定:
修改的代码用红色字体
执行的命令用红色字体,前面加 #
添加的大段代码用蓝色字体
在终端上打印出的信息用紫色字体
出现的错误信息用绿色字体
说明的文字用红色粗体
需要修改的文件加灰色底纹
版本信息:
2009-11-10 V1.0 初稿
2010-03-06 V1.1
1.调整了第 1、3、6部分的内容
2.修改了第 14 部分测试背光驱动的错误
2010-3-16 V1.2
3
手册目录:
一> 准备移植...................................................................................................................... 4
二> 支持NandFlash: ........................................................................................................ 6
三> 支持yaffs2 文件系统 ................................................................................................... 8
四> LCD驱动的移植........................................................................................................... 9
五> DM9000 驱动的移植 ................................................................................................. 12
六> UDA1341 声卡驱动的移植: ................................................................................... 17
七> SD卡驱动移植:........................................................................................................ 20
八> RTC驱动移植: ......................................................................................................... 22
九> 触摸屏驱动移植:.................................................................................................... 22
十> USB设备驱动移植 ..................................................................................................... 24
十一> USB摄像头驱动移植 ............................................................................................. 26
十二> CMOS 摄像头驱动移植 ....................................................................................... 27
十三> 其他字符设备驱动移植........................................................................................ 27
十四> LCD背光驱动移植和开机LOGO的制作.............................................................. 30
十五> 驱动程序在内核源码中的位置及设备名称:.................................................... 31
4
一> 准备移植
获得内核源码:
Linux-2.6.31.tar.bz2(在光盘资料/源码包/kernel 源码目录下)
也可到官方网站http://www.kernel.org/获得最新版本的内核源码
解压源码,进入目录:
#tar xjvf linux-2.6.31.bz2
#cd linux-2.6.31
修改 Makefile: 183 行:
ARCH ?= arm Å指定系统硬件架构
CROSS_COMPILE ?= arm-linux- Å指定交叉编译器
修改时钟:
修改 arch/arm/mach-s3c2440/mach-smdk2440.c 163 行
static void __init smdk2440_map_io(void)
{
s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
s3c24xx_init_clocks(12000000); Å输入时钟为 12MHz
s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
}
这个一定要设置对,否则会打印出乱码。
修改机器码(根据实际情况,这个要和 bootloader 的匹配):
修改:arch/arm/tools/mach-types 379 行:
s3c2440 ……………………… XXX 后面那个数就是机器码
配置:
#make menuconfig Å进入图形化配置界面
在配置菜单中选择这一项:“Load an Alternate Configuration File”
输入 2440 的默认配置文件:arch/arm/configs/s3c2410_defconfig
说明:这个文件就是 S3C24XX 系列开发板的板级支持包(BSP)
然后选择 OK,按回车
进入“System Type”选项单,里面的选项保持默认
在“S3C24XX Machine”选项中只配置这几项(其他的选项取消):
5
S3C2410 Machine --->
[*] SMDK2410/A9M2410
S3C2440 Machine --->
[*] SMDK2440
[*] SMDK2440 with S3C2440 cpu moudle
配置完后,回到主菜单,选择这一项“Save an Alternate Configuration File”
输入要保存的配置文件名称:.config (默认) 或自己取名:TX2440A_config
退出,编译内核: #make zImage
说明:以后移植过程中的配置、编译,都是按这个步骤进行,但是只需要保存
一次配置文件,以后就不需要再保存配置文件了,配置完后可以直接退出。
编译完后,会在 arch/arm/boot 下生成 zImage 内核镜像文件
可以修改该目录下的 Makefile: 在第 57 行下面添加:
@cp –f arch/arm/boot/zImage zImage
@echo ` Kernel: $@ is ready`
这样执行 make zImage 后,就把生成的 zImage 拷到内核根目录下
如果希望在在执行 make distclean 时,也同时把 zImage 删除,
可以修改内核源码目录下 Makefile 的第 1247 行,在后面加上:
-type f –print | xargs rm –f rm zImage
把 zImage 镜像烧进 NandFlash 跑一下,看是否正常打印出信息
如果第一步能正常引导内核,那就开始进行第二步,添加驱动
注意,系统启动最后可能会出现这个错误:
Kernel panic - not syncing: Attempted to kill init!
然后出打印出一些很乱的东西。
因为用 4.X.X 版本的交叉编译器使用 EABI,但内核默认是不支持 EABI 编译的,所以
编译出的系统会报错,但用 3.X.X 版本的编译器就不会出现这个问题。
解决
办法
鲁班奖评选办法下载鲁班奖评选办法下载鲁班奖评选办法下载企业年金办法下载企业年金办法下载
是,配置内核支持 EABI 编译
Kernel Features --->
[*] Use the ARM EABI to compile the kernel
[*] Allow old ABI binaries to run with this kernel
(EXPERIMENTA)
6
二> 支持 NandFlash:
修改:arch/arm/plat-s3c24xx/common-smdk.c 文件,在第 110 行:
这里我们要使 nandflash 同时支持 64M,256M 或更高容量。
static struct mtd_partition smdk_default_nand_part[] = {
#if defined(CONFIG_64M_NAND)
[0] = {
.name = "boot",
.offset = 0,
.size = SZ_1M,
},
[1] = {
.name = "kernel",
.offset = SZ_1M + SZ_128K,
.size = SZ_4M,
},
[2] = {
.name = "yaffs2",
.offset = SZ_1M + SZ_128K + SZ_4M,
.size = SZ_64M - SZ_4M - SZ_1M - SZ_128K,
}
#elif defined(CONFIG_256M_NAND)
[0] = {
.name = "boot",
.offset = 0,
.size = SZ_1M,
},
[1] = {
.name = "kernel",
.offset = SZ_1M + SZ_128K,
.size = SZ_4M,
},
[2] = {
.name = "yaffs2",
.offset = SZ_1M + SZ_128K + SZ_4M,
.size = SZ_256M - SZ_4M - SZ_1M – SZ_128K,
7
}
#endif
};
这个分区名字可以随便起。
接下来修改 Nand 读写匹配时间,这个改不改应该问题都不大,我认为是根据 Nand
的读写特性相关的,也就是查芯片资料得到的值,每种 Nand 的值都不一样,还是在
这个文件中第 140 行:
static struct s3c2410_platform_nand smdk_nand_info = {
.tacls = 10,
.twrph0 = 25,
.twrph1 = 10,
.nr_sets = ARRAY_SIZE(smdk_nand_sets),
.sets = smdk_nand_sets,
};
修改 Kconfig 文件,在配置时选择 NAND 类型,修改 driver/mtd/nand/Kconfig,在
172 行,添加:
choice
prompt "Nand Flash Capacity Select"
depends on MTD
config 64M_NAND
boolean "64M NAND For TX-2440A"
depends on MTD
config 256M_NAND
boolean "256M NAND For TX-2440A"
depends on MTD
endchoice
配置内核,支持 NandFlash
Device Drivers --->
<*> Memory Technology Device (MTD) support --->
8
[*] MTD partitioning support
<*> NAND Device Support --->
<*> NAND Flash support for S3C2410/S3C2440 SoC
[*] S3C2410 NAND Hardware ECC //这个一定要选上
Nand Flash Capacity Select(256M Nand For TX-2440A)--->
启动时输出:
S3C24XX NAND Driver, (c) 2004 Simtec Electronics
s3c24xx-nand s3c2440-nand: Tacls=1, 10ns Twrph0=3 30ns, Twrph1=1 10ns
s3c24xx-nand s3c2440-nand: NAND hardware ECC
NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB 3,3V
8-bit)
Scanning device for bad blocks
Creating 3 MTD partitions on "NAND 256MiB 3,3V 8-bit":
0x000000000000-0x000000100000 : "boot"
0x000000120000-0x000000520000 : "kernel"
0x000000520000-0x000010000000 : "yaffs2"
三> 支持 yaffs2 文件系统
下载 yaffs2 源码(在光盘资料/源码包/其他软件源码/目录下)
解压,进入 yaffs2 目录:
#tar xzvf yaffs2.tar.gz
#cd cvs/yaffs2/
给内核打上 yaffs2 文件系统的补丁,执行:
#./patch-ker.sh c /………/linux-2.6.31/ Å这个是你的内核源码的目录
这时内核源码 fs 目录下多了一个 yaffs2 目录,同时 Makefile 文件和 Kconfig
文件也增加了 yaffs2 的配置和编译条件。
配置对 yaffs2 支持:
这部分配置的比较多,可根据自己的需要进行配置,把不用的文件系统都去掉,
下面是几个主要的配置:
File systems --->
DOS/FAT/NT Filesystems --->
<*> MSDOS fs support
9
<*> VFAT (Windows95) fs support
Miscellaneous filesystems --->
<*> YAFFS2 file system support
[*] Autoselect yaffs2 format
配置语言选项:
Native Language support --->
(iso8859-1) Default NLS Option
<*> Codepage 437(United States, Canada)
<*> Simplified Chinese charset(CP936, GB2312)
<*> NLS ISO8859-1 (Latin 1; Western European Language)
<*> NLS UTF-8
说明:现在内核已经支持 NandFlash 和 yaffs2 文件系统,将内核烧入 NandFlash
后,再烧入 yaffs2 文件系统,可以使用制作好的文件系统,也可以自己制作,详细
的制作文件系统方法,请查看《文件系统制作手册》
启动时(成功挂载文件系统)输出:
yaffs: dev is 32505858 name is "mtdblock2"
yaffs: passed flags ""
yaffs: Attempting MTD mount on 31.2, "mtdblock2"
yaffs: auto selecting yaffs2
yaffs_read_super: isCheckpointed 0
VFS: Mounted root (yaffs filesystem) on device 31:2.
Freeing init memory: 196K
四> LCD 驱动的移植
内核里已经有很完善的 LCD 驱动了,只要根据所用的 LCD 进行简单的修改,在
内核源码 drivers/video/s3c2410fb.c 是 LCD 驱动的源码,首先要设置 LCD 的时钟
频率,有一个计算公式,很复杂,不用管它,直接修改程序实现。
在第 365 行开始的函数:
static void s3c2410fb_activate_var(struct fb_info *info)
{
10
struct s3c2410fb_info *fbi = info->par;
void __iomem *regs = fbi->io;
int type = fbi->regs.lcdcon1 & S3C2410_LCDCON1_TFT;
struct fb_var_screeninfo *var = &info->var;
struct s3c2410fb_mach_info *mach_info = fbi->dev->platform_data;
struct s3c2410fb_display *default_display = mach_info->displays +
mach_info->default_display;
int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock) / 2;
dprintk("%s: var->xres = %d\n", __func__, var->xres);
dprintk("%s: var->yres = %d\n", __func__, var->yres);
dprintk("%s: var->bpp = %d\n", __func__, var->bits_per_pixel);
if (type == S3C2410_LCDCON1_TFT) {
s3c2410fb_calculate_tft_lcd_regs(info, &fbi->regs);
--clkdiv;
if (clkdiv < 0)
clkdiv = 0;
} else {
s3c2410fb_calculate_stn_lcd_regs(info, &fbi->regs);
if (clkdiv < 2)
clkdiv = 2;
}
// fbi->regs.lcdcon1 |= S3C2410_LCDCON1_CLKVAL(clkdiv);
fbi->regs.lcdcon1 |=
S3C2410_LCDCON1_CLKVAL(default_display->setclkval);
这几句是在 s3c2410fb_display 结构体中加入了 setclkval 变量,我们需要在结构
体原型中加入这个变量,在 arch/arm/mach-s3c2410/include/mach/fb.h 中第 40 行
加入:unsigned setclkval; /*clkval*/
说明:在视频教程中修改 s3c2410fb.c 文件时,和手册上有一点误差,手册上写的
是正确的,请按照手册上操作
修改 LCD 参数配置:(这个要查看所用 LCD 的手册来确定参数)
修改 arch/arm/mach-s3c2440/mach-smdk2440.c 中第 107 行的结构体,我修改的参
11
数如下:
static struct s3c2410fb_display smdk2440_lcd_cfg __initdata = {
.lcdcon5 = S3C2410_LCDCON5_FRM565 |
S3C2410_LCDCON5_INVVLINE |
S3C2410_LCDCON5_INVVFRAME |
S3C2410_LCDCON5_PWREN |
S3C2410_LCDCON5_HWSWP,
.type = S3C2410_LCDCON1_TFT,
.width = 320,
.height = 240,
.pixclock = 100000, /* HCLK 60 MHz, divisor 10 */
.setclkval = 0x3, /*add by xgc*/
.xres = 320,
.yres = 240,
.bpp = 16,
.left_margin = 19,
.right_margin = 24,
.hsync_len = 44,
.upper_margin = 7,
.lower_margin = 5,
.vsync_len = 15,
};
屏蔽掉第 150 行的语句:
// .lpcsel = ((0xCE6) & ~7) | 1<<4,
配置内核,支持 LCD:
Device Drivers:
Graphics Support --->
<*>support for frame buffer devices --->
[*] Enable frameware EDID
[*] Enable Vidoe Mode Handling Helpers
12
<*> S3C24X0 LCD framebuffer support
Console display driver support --->
<*> Framebuffer Console Support
[*] Bootup Logo --->
<*> Standard 224-color Linux logo
启动时输出:
Console: switching to colour frame buffer device 40x30
fb0: s3c2410fb frame buffer device
五> DM9000 驱动的移植
修改 arch/arm/mach-s3c2440/mach-smdk2440.c 160 行
Platform_device 结构体中,加入:
&s3c_device_dm9000,
修改 arch/arm/plat-s3c24xx/devs.c 在最前面 38 行加入:
#include
//别忘加这个头文件
/*DM9000*/
static struct resource s3c_dm9000_resource[] = {
[0] = {
.start = S3C2410_CS4,
.end = S3C2410_CS4 + 3,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = S3C2410_CS4 + 4,
.end = S3C2410_CS4 + 4 + 3,
.flags = IORESOURCE_MEM,
},
[2] = {
.start = IRQ_EINT18, /*use eint18 GPG10*/
.end = IRQ_EINT18,
13
.flags = IORESOURCE_IRQ,
}
};
static struct dm9000_plat_data s3c_dm9000_platdata = {
.flags = DM9000_PLATF_16BITONLY,
};
static struct platform_device s3c_device_dm9000 = {
.name = "dm9000",
.id = 0,
.num_resources = ARRAY_SIZE(s3c_dm9000_resource),
.resource = s3c_dm9000_resource,
.dev = {
.platform_data = &s3c_dm9000_platdata,
}
};
EXPORT_SYMBOL(s3c_device_dm9000);
在 arch/arm/plat-s3c/include/plat/devs.h 中加入一行:
extern struct platform_device s3c_device_dm9000;
编译时出现一个奇怪的错误:
arch/arm/plat-s3c24xx/devs.c:63: error: static declaration of
's3c_device_dm9000' follows non-static declaration
arch/arm/plat-s3c/include/plat/devs.h:27: error: previous declaration of
's3c_device_dm9000' was here
s3c_device_dm9000 首先在 devs.c 中定义,在 devs.h 中声明,在 mach-s3c2440.c
中使用,看了好几遍代码,应该没什么问题。查不到什么原因,我觉得是跟编译器
有关,在 devs.c 中做了一下修改,问题解决,编译时只出现一个 warning
把 devs.c 中的这句:
static struct platform_device s3c_device_dm9000 = {
的 static 改成 extern,就可以了
14
下面修改 dm9000.c 源码,在 drivers/net/dm9000.c 中
1. 添加头文件,在第 43 行加入:
#if defined(CONFIG_ARCH_S3C2410)
#include
#endif
2. 指定注册时的中断触发方式,在第 1019 行加入:
static int dm9000_open(struct net_device *dev)
{
…………
irqflags |= IRQF_SHARED;
#if defined (CONFIG_ARCH_S3C2410)
if(request_irq(dev->irq,&dm9000_interrupt,IRQF_SHARED|IRQF_TRIGGER_RI
SING,dev->name,dev))
#else
if(request_irq(dev->irq,&dm9000_interrupt,IRQF_SHARED,dev->name,dev))
#endif
//if (request_irq(dev->irq, &dm9000_interrupt, irqflags, dev->name,
dev))
return -EAGAIN;
…………
}
3. 设置 BANK4, 设置 MAC 地址,在 1215 行,dm9000_probe 函数中加入:
int ret = 0;
int iosize;
int i;
u32 id_val;
#if defined(CONFIG_ARCH_S3C2410)
unsigned int oldval_bwscon = *(volatile unsigned int *)S3C2410_BWSCON;
unsigned int oldval_bankcon4 = *(volatile unsigned int
*)S3C2410_BANKCON4;
#endif
15
/* Init network device */
ndev = alloc_etherdev(sizeof(struct board_info));
if (!ndev) {
dev_err(&pdev->dev, "could not allocate device.\n");
return -ENOMEM;
}
在 1231 行加入:
SET_NETDEV_DEV(ndev, &pdev->dev);
dev_dbg(&pdev->dev, "dm9000_probe()\n");
#if defined(CONFIG_ARCH_S3C2410)
*((volatile unsigned int *)S3C2410_BWSCON) = (oldval_bwscon & ~(3<<16))
| S3C2410_BWSCON_DW4_16 | S3C2410_BWSCON_WS4 | S3C2410_BWSCON_ST4;
*((volatile unsigned int *)S3C2410_BANKCON4) = 0x1f7c;
#endif
在 1390 行加入:
db->mii.mdio_read = dm9000_phy_read;
db->mii.mdio_write = dm9000_phy_write;
#if defined(CONFIG_ARCH_S3C2410)
printk("Now use the default MAC address: 08:90:90:90:90:90 ");
mac_src = "www.txmcu.com";
ndev->dev_addr[0] = 0x08;
ndev->dev_addr[1] = 0x90;
ndev->dev_addr[2] = 0x90;
ndev->dev_addr[3] = 0x90;
ndev->dev_addr[4] = 0x90;
ndev->dev_addr[5] = 0x90;
#else
mac_src = "eeprom";
/* try reading the node address from the attached EEPROM */
16
for (i = 0; i < 6; i += 2)
dm9000_read_eeprom(db, i / 2, ndev->dev_addr+i);
if (!is_valid_ether_addr(ndev->dev_addr) && pdata != NULL) {
mac_src = "platform data";
memcpy(ndev->dev_addr, pdata->dev_addr, 6);
}
if (!is_valid_ether_addr(ndev->dev_addr)) {
/* try reading from mac */
mac_src = "chip";
for (i = 0; i < 6; i++)
ndev->dev_addr[i] = ior(db, i+DM9000_PAR);
}
if (!is_valid_ether_addr(ndev->dev_addr))
dev_warn(db->dev, "%s: Invalid ethernet MAC address. Please "
"set using ifconfig\n", ndev->name);
#endif
platform_set_drvdata(pdev, ndev);
ret = register_netdev(ndev);
if (ret == 0)
printk(KERN_INFO "%s: dm9000%c at %p,%p IRQ %d MAC: %pM (%s)\n",
ndev->name, dm9000_type_to_char(db->type),
db->io_addr, db->io_data, ndev->irq,
ndev->dev_addr, mac_src);
return 0;
out:
#if defined(CONFIG_ARCH_S3C2410)
*(volatile unsigned int *)S3C2410_BWSCON = oldval_bwscon;
*(volatile unsigned int *)S3C2410_BANKCON4 = oldval_bankcon4;
#endif
17
配置内核,支持网卡:
Device Drivers --->
[*] Network device support --->
[*] Ethernet(10 or 100 Mbit) --->
<*> DM9000 support
(4) DM9000 maximum debug level
启动时输出:
dm9000 Ethernet Driver, V1.31
Now use the default MAC address: 08:90:90:90:90:90
eth0: dm9000e at c881c000,c8820004 IRQ 62 MAC: 08:90:90:90:90:90
系统启动后,可能会出现这个错误:
ifconfig: SIOCSIFFLAGS: Cannot assign requested address
原因是 MAC 地址没有设置或没有设置对,在启动脚本中加上:
ifconfig eth0 down
ifconfig eth0 hw ether XX:XX:XX:XX:XX:XX ÅMAC 地址,随便设
ifconfig eth0 up
一般问题可以解决,如果还提示有错,再改一下 MAC 地址
测试网卡的方法:连接好计算机和开发板之间的网线,如果网开发板网卡的灯亮起,
说明已经连接到计算机;
可以在计算机的命令行窗口下(开始->运行->cmd)使用 PING 命令测试网络:
ping 192.168.1.10 Å开发板的 IP 地址
也可以在开发板的串口终端下 PING 计算机的网卡
六> UDA1341 声卡驱动的移植:
硬件接法:L3MODE -> GPB2 L3DATA->GPB3 L3CLOCK->GPB4
内核自带的声卡驱动,可以正常编译,也会打印出正确的配置信息,但是播放
时没有声音,也不能进行录音。要替换掉内核自带的驱动(注意先备份),用 2.6.29.4
内核中的声卡驱动
将 2.6.29.4 内 核 源 码 ( 光 盘 资 料 -> 源 码 包 ->kernel 源 码
18
->linux-2.6.29.4.tar.bz2)目录下的:
sound 文件夹,
include/sound 文件夹,
include/asm-arm/plat-s3c24xx 文件夹,
arch/arm/mach-s3c2410/include/mach/audio.h 文件
复制到 2.6.31 内核源码的相应目录下,
声卡驱动的移植步骤和 DM9000 的移植大体相同
修改 arch/arm/mach-s3c2440/mach-smdk2440.c 161 行
Platform_device 结构体中,加入:
&s3c24xx_uda134x,
修改 arch/arm/plat-s3c24xx/devs.c,在 DM9000 那段代码下面加入:
static struct s3c24xx_uda134x_platform_data s3c24xx_uda134x_data = {
.l3_clk = S3C2410_GPB(4),
.l3_data = S3C2410_GPB(3),
.l3_mode = S3C2410_GPB(2),
.model = UDA134X_UDA1341,
};
extern struct platform_device s3c24xx_uda134x = {
.name = "s3c24xx_uda134x",
.dev = {
.platform_data = &s3c24xx_uda134x_data,
}
};
EXPORT_SYMBOL(s3c24xx_uda134x);
在 arch/arm/plat-s3c/include/plat/devs.h 中加入一行:
extern struct platform_device s3c24xx_uda134x;
注意:编译时会出错,提示 S3C2410_GPBX,UDA134X_UDA1341,l3_mode 等没有定义,
这里需要在 devs.c 中包含两个头文件
#include //这个是 S3C2410 的 GPIO 定义
19
#include
配置内核,支持声卡:
Device Drivers:
* Sound card support Æ
* Advanced Linux Sound ArchitectureÆ
* CCS Mixer API
* CSS PCM(digital audio) API
* Verbose procfs contents
* ALSA for SoC audio supportÆ
* SoC audio for the Samsung S3C24XX chips
* SoC I2S Audio support for UDA134X wired to a S3C24XX
编译内核,会报错:
Sound/core/info.c:159:error:’struct proc_dir_entry’has no member named
‘owner’
Sound/core/info.c:982:error:’struct proc_dir_entry’has no member named
‘owner’
在 include/linux/proc_fs.h 文件中定义这个结构体成员,在第 70 行加入:
struct module *owner;
继续编译,又会出现一个错误:
Sound/soc/s3c24xx/s3c24xx-i2s.c:407:error:implicit declaration of function
‘s3c2410_gpio_cfgpin’
在 2.6.31 内核中,s3c2410_gpio_cfgpin 是在 include/linux/gpio.h 中定义的,要
添加这个文件
在 sound/soc/s3c24xx/s3c24xx-i2s.c 中,第 24 行添加:
#include
继续编译,又会出现很多错误:
sound/soc/s3c24xx/s3c24xx-pcm.c 中的 S3C2410_DISRCC_INC 等常量没有定义,
s3c2410_dam_config 函数的参数个数不对
原因是 2.6.31 内核中 dma 相关的文件改变了,以前的跟 dma 有关的代码就不能使用
了,我们只需把原来代码中的 sound/soc/s3c24xx/s3c24xx-pcm.c 这个文件替换回
来就可以了。
20
编译时同样会出现和 DM9000 一样的错误,解决方法也是把
static struct platform_device s3c24xx_uda134x = {
(static 改成 extern)
如果没有问题了,启动时会打印出以下信息:
Advanced Linux Sound Architecture Driver Version 1.0.18a.
No device for DAI UDA134X
No device for DAI s3c24xx-i2s
S3C24XX_UDA134X SoC Audio driver
UDA134X SoC Audio Codec
asoc: UDA134X <-> s3c24xx-i2s mapping ok
ALSA device list:
#0: S3C24XX_UDA134X (UDA134X)
前面两句不用管,只要后面的信息都打出来就 OK 了,可以在源码下把这两条警告给
屏蔽掉
下面测试一下声卡,设备名称为:/dev/dsp
用命令: #cat /dev/dsp > /tmp/1.wav 进行录音,录完后 Ctrl+C
用命令:#cat /tmp/1.wav > /dev/dsp 进行放音,如果听到刚才的录音,就说明声
卡好使了,再用 madplay 测试一下音质,一般都没什么问题。
七> SD 卡驱动移植:
内核自带 SD 卡驱动,在 drivers/mmc/目录下
在 arch/arm/mach-s3c2440/mach-smdk2440.c plat_device 结构体中加入:
&s3c_device_sdi,
修改 drivers/mmc/host/s3cmci.c 在 1335 行加入
host->irq_cd = IRQ_EINT16;
s3c2410_gpio_cfgpin(S3C2410_GPG8, S3C2410_GPG8_EINT16);
这两句指定 SD 的中断为 EINT16
修改同文件,屏蔽掉 1358-1359 行:
if (s3c2410_dma_request(S3CMCI_DMA, &s3cmci_dma_client, NULL) < 0) {
dev_err(&pdev->dev, "unable to get DMA channel.\n");
21
// ret = -EBUSY;
// goto probe_free_irq_cd;
}
再将 114