移植Linux3.4.2版本内核到mini2440(二)--添加网卡、UVC摄像头、LCD驱动 2014-01-01
11:36:45
分类:
嵌入式
移植Linux3.4.2版本内核到mini2440(二)--添加网卡、UVC摄像头、LCD驱动
该移植工作主要参考了韦东山的《嵌入式Linux应用开发完全手册》,第二期毕业班视频教程和友善之臂mini2440光盘提供的《Mini2440 Linux移植开发实战指南.pdf》,使用的bootloader是我根据韦东山老师制作的2012.04.01版本u-boot,具体制作方法可参考我的另一篇博客《u-boot-2012.04.01修改移植和制作补丁文件 》,交叉编译器使用的是arm-linux-gcc
: v4.3.2。本篇博客续《 移植Linux3.4.2版本内核到mini2440(一) 》。
一、添加网卡驱动
韦东山老师在第三期项目班中提供了适用于mini2440版本的Linux3.4.2版本补丁linux3.4.2_mini2440.patch,从官方www.kernel.org下载内核源码,打上该补丁进行了简单的测试,发现该补丁提供的网卡驱动还有LCD驱动并不适用于我的MINI2440_T35,所以自己参考第二期视频教程移植了网卡驱动等。
1.1 利用内核提供的驱动测试网卡
自Linux2.6.31开始,Linux内核已经开始官方支持了Mini2440,Mini2440的机器ID是1999(7CF),先利用内核为Mini2440提供的ID测试网卡,步骤如下:
# set set machid 7CF //将机器ID设置为7CF
# boot
结果发现mini2440启动后可正常启动网卡,挂载NFS文件系统等,但是我们的移植工作是采用的SMDK2440的机器ID:16A,内核并未对该单板设置对网卡的支持,参考mini2440的单板配置文件arch/arm/mach-s3c24xx/mach-mini24402440.c,修改SMDK2440的单板配置文件arch/arm/mach-s3c24xx/mach-smdk2440.c,主要作了如下修改。
1.2 修改arch/arm/mach-s3c24xx/mach-smdk2440.c
a. 添加头文件
#include
b.基址定义
#define MACH_SMDK2440_DM9K_BASE (S3C2410_CS4 + 0x300)
c.添加如下结构体等
点击(
此处)折叠或打开
-
/* DM9000AEP 10/100 ethernet controller */
static struct resource smdk2440_dm9k_resource[] = {
[0] = {
.start = MACH_SMDK2440_DM9K_BASE,
.end = MACH_SMDK2440_DM9K_BASE + 3,
.flags = IORESOURCE_MEM
},
[1] = {
.start = MACH_SMDK2440_DM9K_BASE + 4,
.end = MACH_SMDK2440_DM9K_BASE + 7,
.flags = IORESOURCE_MEM
},
[2] = {
.start = IRQ_EINT7,
.end = IRQ_EINT7,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
}
};
/*
* The DM9000 has no eeprom, and it's MAC address is set by
* the bootloader before starting the kernel.
*/
static struct dm9000_plat_data smdk2440_dm9k_pdata = {
.flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),
};
static struct platform_device smdk2440_device_eth = {
.name = "dm9000",
.id = -1,
.num_resources = ARRAY_SIZE(smdk2440_dm9k_resource),
.resource = smdk2440_dm9k_resource,
.dev = {
.platform_data = &smdk2440_dm9k_pdata,
},
};
d.在smdk2440设备集中加入对网卡驱动的支持
点击(
此处)折叠或打开
-
static struct platform_device *smdk2440_devices[] __initdata = {
-
&s3c_device_ohci,
-
&s3c_device_lcd,
-
&s3c_device_wdt,
-
&s3c_device_i2c0,
-
&s3c_device_iis,
-
&smdk2440_device_eth, //新添加
-
}
1.3 编译、下载测试
# make uImage
# cp arch/arm/boot/uImage /work/tftpboot/uImage_3.4.2
# tftp 30000000 uImage_3.4.2
# nand erase.part kernel; nand write 30000000 kernel
# set machid 16a //设置为SMDK2440的机器ID
# boot
1.4 结果可看到网卡正常工作了~~~
二、添加UVC摄像头驱动
2.1 配置内核
# make menuconfig
Device Drivers --->
<*> Multimedia support --->
<*> Video For Linux
[*] Video capture adapters --->
[*] V4L USB devices --->
<*> USB Video Class (UVC) //加上该项
# make uImage
# cp arch/arm/boot/uImage /work/tftpboot/uImage_3.4.2
# tftp 30000000 uImage_3.4.2
# nand erase.part kernel; nand write 30000000 kernel
启动之后即可在dev目录下发现video0,前提是要在开发板挂接UVC摄像头,可用我前面博客《Ubuntu10.04中利用V4L2读取摄像头数据并保存成文件 》提到的程序编译出arm版本进行测试,才我的mini2440上可进行正常采集保存。
三、移植LCD驱动
修改自韦东山老师提供的MINI2440源码中驱动部分的10th_lcd.rar,该驱动程序并不适用于我的mini2440_t35,主要是修改lcdcon1,2,3,4,5
这几个寄存器的值。先以模块的形式测试该驱动程序,没有错误之后再编译进内核。
3.1 以模块形式测试该驱动中的4th中的lcd.c
修改Makefile
点击(此处)折叠或打开
-
KERN_DIR = /work/kernel/linux-3.4.2_mini2440
-
-
all:
-
make -C $(KERN_DIR) M=`pwd`
modules
-
-
clean:
-
make -C $(KERN_DIR) M=`pwd`
modules clean
-
rm -rf modules.order
-
-
obj-m += lcd.o
# make
出错,去掉如下三个头文件
点击(此处)折叠或打开
-
//#include <asm/arch/regs-lcd.h>
-
//#include <asm/arch/regs-gpio.h>
-
//#include <asm/arch/fb.h>
针对Mini2440的LCD_t35,修改如下几个寄存器的值,韦老师提供的是针对320*240的LCD,而我的LCD是240*320的,这部分做相应修改。
点击(此处)折叠或打开
-
lcd_regs->lcdcon1 = (4<<8) | (3<<5) | (0x0d<<1);
-
lcd_regs->lcdcon2 = (5<<24) | (319<<14) | (3<<6) | (1<<0);
-
lcd_regs->lcdcon3 = (25<<19) | (239<<8) | (0<<0);
-
lcd_regs->lcdcon4 = 4;
-
lcd_regs->lcdcon5 = (0<<10) | (1<<9) | (1<<8) | (0<<12) | (0<<1) | (0<<0)
# make
# cp lcd.ko /work/nfsroot/fs_mini_mdev_new
编译内核,去掉内核自带的LCD驱动
# make menuconfig
Device Drivers --->
Graphics support --->
<*> Support for frame buffer devices --->
S3C2410 LCD framebuffer support //编译为模块,把其他选项都去掉
# make modules //编译出lcd需要的模块
# make uImage
# cp arch/arm/boot/uImage /work/tftpboot/uImage_nolcd
以NFS方式挂载根文件系统
# tftp 30000000 uImage_nolcd
# nand erase.part kernel; nand write 30000000 kernel
# set bootargs noinitrd root=/dev/nfs nfsroot=192.168.1.121:/work/nfsroot/fs_mini_mdev_new ip=192.168.1.17 console=ttySAC0,115200
# boot
进入系统后挂载lcd模块
# insmod lcd.ko
出现如下错误,原因是缺少对应模块。
lcd: Unknown symbol cfb_copyarea (err 0)
lcd: Unknown symbol cfb_imageblit (err 0)
lcd: Unknown symbol cfb_fillrect (err 0)
insmod: can't insert 'lcd.ko': unknown symbol in module or invalid parameter
添加这几个模块<内核目录执行>
# cd drivers/video/
# cp cfb*.ko /work/nfsroot/fs_mini_mdev_new
# insmod cfbcopyarea.ko
# insmod cfbfillrect.ko
# insmod cfbimgblt.ko
# insmod lcd.ko
测试,用MINI2440源码drivers_and_test提供的fb_test.rar测试该驱动
# ./fb_test /dev/fb0
结果OK。
3.2 将LCD驱动添加进内核
将上面修改好的lcd.c放到内核的drivers/video目录,命名为lcd_mini2440.c,附上我修改好的文件lcd_mini2440.rar
添加对LCD的支持
# make menuconfig
Device Drivers --->
Graphics support --->
<*> Support for frame buffer devices --->
<*> S3C2410 LCD framebuffer support //编译进内核
修改drivers/video/Makefile
-obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o
+obj-$(CONFIG_FB_S3C2410) += lcd_mini2440.o
# make uImage
# cp arch/arm/boot/uImage /work/tftpboot/uImage_lcd
# tftp 30000000 uImage_lcd
# nand erase.part kernel; nand write 30000000 kernel
# boot
系统启动后在/dev目录下即可看到LCD对应设备fb0
运行测试程序fb_test,结果OK,制作了移植了DM9000,UVC,LCD驱动的补丁文件linux_3.4.2_mini2440_dm9000_uvc_lcd.patch。