TX2440A的内核移植手册(很好,已经成功,内核2.6.31)

1

Linux-2.6.31 内核移植手册

2010-12-31 v1.5

手册内容简介:

本手册是天祥电子推出的TX-2440A 开发板的配套手册之一,全面分析了LINUX操作系统内核在嵌入式开发板上的移植过程,手册中的部分内容都会在配套的视频教程中(第十五讲,第十六讲)进行讲解。

在开始进行移植之前,需要了解LINUX内核和驱动的相关知识,安装基本的开发工具,搭建好开发环境;建议先看视频教程学习,在具备了一定的能力后再来参考本手册来操作。

本手册分为16个部分,第1部分,准备移植,要先掌握这一部分的操作方法,包括(修改代码,配置内核选项,编译内核镜像,下载内核镜像到开发板,启动系统),然后再进入后面的部分。第2、3部分是为挂载文件系统做准备,这里容易出现错误(比如:文件系统不能成功挂载),可以先学习文件系统的相关知识(视频教程第十七讲),自己制作文件系统(参考《文件系统制作手册》),在能成功挂载文件系统后,再进入后面的部分。第4-14部分都是针对开发板上的硬件的驱动移植,还介绍了硬件驱动的测试方法。第15部分列出了驱动程序在内核源码中的位置及设备名称,方便大家查阅。第16部分是内核更新的内容,对内核的功能和驱动进行优化。

由于个人能力有限,手册中难免会出现一些笔误和不足之处,如果发现问题,请及时提出,可以发到我们的论坛https://www.360docs.net/doc/f115506192.html,/上,在学习过程中遇到的问题,可以联系我们,我们会提供技术支持。

本手册中的所有内容目前仅适用于TX2440A开发板,如果将其用在其他的开发板上,出现的一切问题,我们一律不提供技术支持。

最好不要从手册中直接复制代码,因为在编写手册时,有些字符可能会自动变成全角格式,在代码中是不允许有全角字符的,所以有可能会导致一些错误。所以最好是手动编写代码。

手册中的内容会不定期的更新,以后还会加入更丰富的内容,更新后会放到FTP服务器供大家下载。希望广大的TX2440A开发板用户能多提出宝贵的意见,我们会根据大家的意见及时调整手册中的内容。哈尔滨祥鹏科技有限公司

网址:https://www.360docs.net/doc/f115506192.html,

电话:0451-********

2010年12月31日2

说明:

内核版本:

Linux-2.6.31

交叉编译器版本:

arm-linux-gcc 4.1.2

操作系统平台:

Linux Red Hat 9.0

开发板平台:

arm TX2440A

手册中字体颜色的约定:

修改的代码用红色字体

添加的大段代码用蓝色字体

执行的命令用红色字体,前面加#

在终端上打印出的信息用紫色字体

出现的错误信息用绿色字体

说明的文字用红色粗体

需要修改的文件加灰色底纹

版本信息:

V1.0 2009-11-10

1. 初稿

V1.1 2010-03-06

1. 调整了第1、3、6部分的内容

2. 修改了第14 部分测试背光驱动的错误

V1.2 2010-3-16

V1.3 2010-4-21

1. 加入了内核更新(第十六章)

V1.4 2010-6-17

1. 加入了7寸LCD 和LOGO的支持(第四章)

2. 加入了串口2驱动(第十六章)

V1.5 2010-12-31

1. 加入了4.3寸LCD和LOGO的支持(第四章)

2. 重新编写OV9650 CMOS摄像头驱动程序ov9650.c和ov9650.h,同时支持

3.5寸屏

(320x240)、4.3寸屏(480x272)、7寸屏(800x480)(第十二章)

3. 修改DS18B20驱动,使读取的温度值稳定(第十六章)

3

手册目录

Linux-2.6.31 内核移植手册 (1)

手册内容简介: (1)

说明: (2)

手册目录 (3)

一、准备移植 (4)

二、支持NandFlash (6)

三、支持yaffs2文件系统 (8)

四、LCD驱动的移植 (9)

五、DM9000驱动的移植 (13)

六、UDA1341声卡驱动的移植 (18)

七、SD 卡驱动移植 (20)

八、RTC 驱动移植 (21)

九、触摸屏驱动移植 (22)

十、USB 设备驱动移植 (23)

十一、USB 摄像头驱动移植 (25)

十二、CMOS 摄像头驱动移植 (25)

十三、其他字符设备驱动移植 (26)

十四、LCD背光驱动移植和开机LOGO的制作 (28)

十五、驱动程序在内核源码中的位置及设备名称 (33)

十六、内核更新...............................................................................................................................34 4

一、准备移植

获得内核源码:

Linux-2.6.31.tar.bz2(在光盘资料/源码包/kernel 源码目录下) ,也可到官网https://www.360docs.net/doc/f115506192.html,/获得最新版本的内核源码。

解压源码,进入目录:

#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"选项中只配置这几项(其他的选项取消):

S3C2410 Machine --->

[*] SMDK2410/A9M2410

S3C2440 Machine --->

[*] SMDK2440

[*] SMDK2440 with S3C2440 cpu moudle

配置完后,回到主菜单,选择这一项"Save an Alternate Configuration File" ,输入要保存的

5

配置文件名称:.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

这里我们要使NandFlash驱动同时支持64M,256M 或更高容量。 修改arch/arm/plat-s3c24xx/common-smdk.c 文件,在第110 行: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,

}

#endif

};

这个分区名字可以随便起。7

接下来修改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 --->

[*] 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":

8

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

<*> 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" 9

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)

{

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*/ 10

说明:在视频教程中修改s3c2410fb.c文件时,和手册上有一点误差,手册上写的是正确的,请按照手册上操作。

修改LCD 参数配置:(这个要查看所用LCD 的手册来确定参数)

修改arch/arm/mach-s3c2440/mach-smdk2440.c 中第107 行的结构体,修改的参数如下: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,

.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

<*> S3C24X0 LCD framebuffer support

Console display driver support --->

<*> Framebuffer Console Support

11

[*] Bootup Logo --->

<*> Standard 224-color Linux logo

启动时输出:

Console: switching to colour frame buffer device 40x30

fb0: s3c2410fb frame buffer device

添加对4.3寸LCD和7寸LCD 的支持:

我们使用的3.5寸屏分辨率是320x240,4.3寸屏分辨率是480x272,7寸屏分辨率是800x480。同样修改arch/arm/mach-s3c2440/mach-smdk2440.c中第107行的结构体,加入4.3寸屏和7寸屏的配置参数:

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,

#if defined(CONFIG_FB_S3C2410_W35)

.width = 320,

.height = 240,

.pixclock = 100000,

.setclkval = 0x3,

.xres = 320,

.yres= 240,

.bpp = 16,

.left_margin = 19,

.right_margin = 24,

.hsync_len = 44,

.upper_margin = 7,

.lower_margin = 5,

.vsync_len = 15,

#elif defined(CONFIG_FB_S3C2410_W43)

.width = 480,

.height = 272,

.pixclock = 40000,

.setclkval = 0x4, 12

.xres = 480,

.yres = 272,

.bpp = 16,

.left_margin = 19,

.right_margin = 10,

.hsync_len = 30,

.upper_margin = 4,

.lower_margin = 2,

.vsync_len = 8,

#elif defined(CONFIG_FB_S3C2410_Q70)

.width = 800,

.height = 480,

.pixclock = 40000,

.setclkval = 0x1,

.xres = 800,

.yres = 480,

.bpp = 16,

.left_margin = 40,

.right_margin = 40,

.hsync_len = 48,

.upper_margin = 13,

.lower_margin = 29,

.vsync_len = 3,

#endif

};

修改drivers/video/Kconfig 文件,在1942行加入:choice

prompt "LCD size select"

depends on FB_S3C2410

help

s3c2410 lcd size select

config FB_S3C2410_W35

boolean"The 3.5 inch LCD with resolution 320X240"

depends on FB_S3C2410

help

3.5 inch LCD 320X240

13

config FB_S3C2410_W43

boolean "The 4.3 inch LCD with resolution 480X272"

depends on FB_S3C2410

help

4.3 inch LCD 480X272

config FB_S3C2410_Q70

boolean"The 7 inch LCD with resolution 800X480"

depends on FB_S3C2410

help

7 inch LCD 800X480

endchoice

config FB_S3C2410_DEBUG

bool "S3C2410 lcd debug messages"

depends on FB_S3C2410

help

Turn on debugging messages. Note that you can set/unset at run time

through sysfs

配置内核,支持4.3寸LCD和7寸LCD:

Device Drivers:

Graphics Support --->

<*>support for frame buffer devices --->

<*> S3C24X0 LCD framebuffer support

LCD size select(The 3.5 inch LCD with resolution 320X240) --->

进入"LCD size select(The 3.5 inch LCD with resolution 320X240)--->"选项,在这里选择不同的LCD类型,按空格键即可选中,前面有"X"的表示选中的,如果我们要选择4.3寸屏,将光标移至第二行,按空格键,就选中了对4.3寸屏的支持。

()The 3.5 inch LCD with resolution 320X240

(X)The 4.3 inch LCD with resolution 480X272

()The 7 inch LCD with resolution 800X480

五、DM9000驱动的移植

修改arch/arm/mach-s3c2440/mach-smdk2440.c的160行,Platform_device 结构体中,加入:&s3c_device_dm9000,

修改arch/arm/plat-s3c24xx/devs.c在最前面38行加入:

#include //别忘加这个头文件

/*DM9000*/

14

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,

.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 15

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,就可以了。

下面修改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_RISING,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 16

/* 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 = "https://www.360docs.net/doc/f115506192.html,";

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*/

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++) 17

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

配置内核,支持网卡:

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 18

一般问题可以解决,如果还提示有错,再改一下MAC地址。

测试网卡的方法:连接好计算机和开发板之间的网线,如果网开发板网卡的灯亮起,说明已经连接到计算机;可以在计算机的命令行窗口下(开始->运行->cmd)使用PING命令测试网络:ping 192.168.1.10 <—开发板的IP 地址

也可以在开发板的串口终端下PING 计算机的网卡。

六、UDA1341声卡驱动的移植

内核自带的声卡驱动,可以正常编译,也会打印出正确的配置信息,但是播放时没有声音,也不能进行录音。要替换掉内核自带的驱动(注意先备份),用2.6.29.4内核中的声卡驱动,将2.6.29.4内核源码(光盘资料->源码包->kernel源码->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内核源码的相应目录下。

修改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;

19

注意:编译时会出错,提示S3C2410_GPBX,UDA134X_UDA1341,l3_mode 等没有定义,这里需要在devs.c 中包含两个头文件,

#include //这个是S3C2410的GPIO定义

#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这个文件替换回来就可以了。

编译时同样会出现和DM9000 一样的错误,解决方法也是把

static struct platform_device s3c24xx_uda134x = {

(static 改成extern)

如果没有问题了,启动时会打印出以下信息:20

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");

// ret = -EBUSY;

// goto probe_free_irq_cd;

}

再将1147-1148行输出的多余信息屏蔽掉:

if ((ios->power_mode == MMC_POWER_ON) ||

(ios->power_mode == MMC_POWER_UP)) {

// dbg(host, dbg_conf, "running at %lukHz (requested: %ukHz).\n",

// host->real_rate/1000, ios->clock/1000);

} else {

dbg(host, dbg_conf, "powered down.\n");

} 21

相关文档
最新文档