1.修改顶层Makefile
ARCH ?= arm
CROSS_COMPILE ?= arm-linux- 根据自己的环境修改交叉编译器前缀
2.修改arch/arm/boot/Makefile增加一行
@echo ' Kernel: $@ is ready'
cp $@ /tftpboot/ 根据自己的ftp服务器目录修改
3.匹配机器码
1) 启动u-boot执行bdinfo将输出开发板的相关信息,包括机器码
TQ2440 # bd
arch_number = 0x0000016A 机器码362
boot_params = 0x30000100
DRAM bank = 0x00000000
-> start = 0x30000000
-> size = 0x04000000
ethaddr = 00:01:02:03:04:05
ip_addr = 192.168.1.100
baudrate = 115200 bps
TLB addr = 0x33FF0000
relocaddr = 0x33F40000
reloc off = 0x33F40000
irq_sp = 0x33B2FF68
sp start = 0x33B2FF58
FB base = 0x00000000
TQ2440 #
2) 新版u-boot可以设置环境变量machid来更改机器码
TQ2440 # set machid 0x16A
3) 内核机器码:arch/arm/mach-s3c2440/mach-smdk2440.c
MACHINE_START(S3C2440,"SMDK2440")
其中的S3C2440即为机器码
再查看arch/arm/tools/mach-types 第379行即为S3C2440所对应的机器码362,必须和u-boot的机器码相同,否则没法启动内核
4.修改系统时钟
arch/arm/mach-s3c2440/mach-smdk2440.c我们的开发板使用12MHZ
s3c24xx_init_clocks(12000000);
5.执行默认配置
root@zjh:/home/work/linux-2.6.36.4#make s3c2410_defconfig
6.配置内核
root@zjh:/home/work/linux-2.6.36.4#make menuconfig
Kernel Features --->
[*] Use the ARM EABI tocompile the kernel
[*] Allow old ABI binaries to run with thiskernel (EXPERIMENTAL)
注:使用4.X.X 版本的交叉编译器一定要选中以上两项,否则会出现Kernel panic - not syncing:Attempted to kill init! 这样的错误以致没法启动内核
System Type --->
S3C2440 and S3C2442Machines --->
[*]SMDK2440
[*]SMDK2440 with S3C2440 CPU module
只选中这两项即可,其他的Machine都取消
7.编译内核
root@zjh:/home/work/linux-2.6.36.4#make zImage
…………
OBJCOPY arch/arm/boot/zImage
Kernel: arch/arm/boot/zImage is ready
ImageName: linux-2.6.36
Created: Wed Oct 17 12:42:19 2012
ImageType: ARM Linux Kernel Image(uncompressed)
DataSize: 2075944 Bytes = 2027.29 kB =1.98 MB
Load Address:30008000
EntryPoint: 30008000
8.启动u-boot,执行如下操作
TQ2440 # tftp30000000 uImage
TQ2440 # bootm30000000
## Booting imageat 30000000 ...
Image Name: linux-2.6.36
Created: 2012-10-17 4:33:02 UTC
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2075944 Bytes = 2 MB
Load Address: 30008000
Entry Point: 30008000
Verifying Checksum ... OK
XIP Kernel Image ... OK
Startingkernel ...
UncompressingLinux... done, booting the kernel.
Linux version2.6.36.4 (root@zjh) (gcc version 4.4.3 (ctng-1.6.1) ) #4 Wed Oct 17 12:32:51CST 2012
CPU: ARM920T[41129200] revision 0 (ARMv4T), cr=c0007177
CPU: VIVT datacache, VIVT instruction cache
Machine:SMDK2440
Memory policy:ECC disabled, Data cache writeback
CPU S3C2440A(id 0x32440001)
S3C24XXClocks, Copyright 2004 Simtec Electronics
S3C244X: core400.000 MHz, memory 100.000 MHz, peripheral 50.000 MHz…………
二、DM9000网卡驱动移植
1.修改arch/arm/mach-s3c2440/mach-smdk2440.c,构建DM9000平台设备
#include <linux/dm9000.h>
#define MACH_TQ2440_DM9K_BASE (S3C2410_CS4 + 0x300)
static struct resource TQ2440_dm9k_resource[] = {
[0] = {
.start =MACH_TQ2440_DM9K_BASE,
.end = MACH_TQ2440_DM9K_BASE + 3,
.flags =IORESOURCE_MEM
},
[1] = {
.start =MACH_TQ2440_DM9K_BASE + 4,
.end = MACH_TQ2440_DM9K_BASE + 7,
.flags =IORESOURCE_MEM
},
[2] = {
.start =IRQ_EINT7,
.end = IRQ_EINT7,
.flags =IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,
}
};
/*
* The DM9000 has noeeprom, and set it's MAC address
*/
static struct dm9000_plat_data TQ2440_dm9k_pdata = {
.flags = (DM9000_PLATF_16BITONLY |DM9000_PLATF_NO_EEPROM),
.dev_addr = "\x00\x11\x22\x33\x44\x66",
};
static struct platform_device TQ2440_device_eth = {
.name = "dm9000",
.id = -1,
.num_resources = ARRAY_SIZE(TQ2440_dm9k_resource),
.resource = TQ2440_dm9k_resource,
.dev = {
.platform_data = &TQ2440_dm9k_pdata,
},
};
smdk2440_devices[]结构体数组添加如下代码
&TQ2440_device_eth
2.修改drivers/net/ethernet/davicom/dm9000.c第44行加入如下代码
#include"dm9000.h"
#ifdefined(CONFIG_ARCH_S3C2440)
#include<mach/regs-mem.h>
#endif
第1375行加入如下代码
u32 id_val;
#ifdefined(CONFIG_ARCH_S3C2440)
unsigned int oldval_bwscon = *(volatileunsigned int *)S3C2410_BWSCON;
unsigned int oldval_bankcon4 = *(volatile unsigned int *)S3C2410_BANKCON4;
#endif
/* Init network device */
第1387行加入如下代码
dev_dbg(&pdev->dev,"dm9000_probe()\n");
#ifdefined(CONFIG_ARCH_S3C2440)
/* 设置Bank4:总线宽度为16,使能nWAIT */
*((volatile unsigned int *)S3C2410_BWSCON) =(oldval_bwscon & ~(3<<16)) |
S3C2410_BWSCON_DW4_16| S3C2410_BWSCON_WS4 | S3C2410_BWSCON_ST4;
/* 设置Bandk4的时间参数 */
*((volatile unsigned int *)S3C2410_BANKCON4)= 0x1f7c;
#endif
/* setup board info structure */
第1615行
out:
/* 恢复寄存器原来的值 */
#ifdefined(CONFIG_ARCH_S3C2440)
*(volatile unsigned int *)S3C2410_BWSCON =oldval_bwscon;
*(volatile unsigned int *)S3C2410_BANKCON4 =oldval_bankcon4;
#endif
3.配置内核支持DM9000
root@zjh:/home/work/linux-2.6.36.4#make menuconfig
[*] Networkingsupport --->
Networkingoptions --->
<*>Packet socket
<*> Unixdomain socket
[*] TCP/IPnetworking
[*] IP: multicasting
[*] IP: kernel level autoconfiguration
[*] IP: BOOTP support
Device Drivers --->
[*] Network device support --->
[*] Ethernet (10 or 100Mbit) --->
<*> DM9000 support
File systems --->
[*] Network File Systems (NEW) --->
<*> NFS client support
[*] NFS client support for NFS version 3 (NEW)
[*] NFS client support for the NFSv3 ACL protocol extension
[*] Root file system on NFS
4.重新编译内核并设置u-boot启动参数,通过NFS挂载根文件系统
TQ2440 # setbootargs root=/dev/nfs nfsroot=192.168.1.8:/home/work/rootfs ip=192.168.1.100init=/linuxrc console=ttySAC0,115200
TQ2440 # save
5.下载内核并启动
TQ2440 # tftp30000000 uImage
TQ2440 # bootm30000000
………………
[root@tq2440/]#
三、移植内核自带的LED驱动
1.在BSP文件arch/arm/mach-s3c2440/mach-smdk2440.c增加我们开发板的LED配置
#include<linux/leds.h>
staticstruct gpio_led tq2440_leds[] = {
[0] = {
.name = "led1",
.gpio = S3C2410_GPB(5),
.active_low = 1,
},
[1] = {
.name = "led2",
.gpio = S3C2410_GPB(6),
.active_low = 1,
},
[2] = {
.name = "led3",
.gpio = S3C2410_GPB(7),
.active_low = 1,
},
[3] = {
.name = "led4",
.gpio = S3C2410_GPB(8),
.active_low = 1,
}
};
staticstruct gpio_led_platform_data tq2440_leds_pdata = {
.num_leds =ARRAY_SIZE(tq2440_leds),
.leds =tq2440_leds,
};
staticstruct platform_device tq2440_device_leds = {
.name ="leds-gpio",
.id =-1,
.dev ={
.platform_data =&tq2440_leds_pdata,
},
};
在smdk2440_devices[]平台数组中添加
&tq2440_device_leds,
2.配置内核
DeviceDrivers --->
-*- LEDSupport --->
<*> LED Class Support
<> LED Support for Samsung S3C24XXGPIO LEDs
<*> LED Support for GPIO connected LEDs
[*] Platform device bindings for GPIO LEDs
3.重新编译内核
[root@tq2440 /]#ll /sys/class/leds/
total 0
drwxr-xr-x 3 root root 0 Jan 1 00:00 led1
drwxr-xr-x 3 root root 0 Jan 1 00:00 led2
drwxr-xr-x 3 root root 0 Jan 1 00:00 led3
drwxr-xr-x 3 root root 0 Jan 1 00:00 led4
[root@tq2440 /]#echo 1 > sys/class/leds/led1/brightness 点亮LED1
[root@tq2440 /]#echo 0 > sys/class/leds/led1/brightness 熄灭LED1
四、RTC驱动移植
1.在arch/arm/mach-s3c2440/mach-smdk2440.c的smdk2440_devices[]结构体数组添加rtc平台设备列表
&s3c_device_rtc,
2.配置内核
DeviceDrivers --->
[*] Real Time Clock --->
[*] Set system time from RTC on startup and resume (NEW)
(rtc0) RTC used to set the system time
[*] /sys/class/rtc/rtcN (sysfs) (NEW)
[*] /proc/driver/rtc (procfs for rtc0) (NEW)
[*] /dev/rtcN (character devices) (NEW)
<*> Samsung S3C series SoC RTC
3.重新编译内核并下载到开发板
[root@tq2440 /]#date
Thu Jan 1 00:09:48 UTC 1970
[root@tq2440 /]#date -s 2012.10.17-22:30:0 设置时间
Wed Oct 1722:30:00 UTC 2012
[root@tq2440 /]#hwclock -w 设置硬件时间为当前系统时间
这样系统重启后会自动更新到硬件时间
五、LCD驱动移植
1.在arch/arm/mach-s3c2440/mach-smdk2440.c中修改LCD参数
.width = 480,
.height =272,
.pixclock =((2 * 1000000000000LL)/(60 * (2 + 2 + 41 + 480) * (2 + 2 + 10 + 272))),
.xres =480,
.yres =272,
.bpp =16,
.left_margin = 2,
.right_margin = 2,
.hsync_len = 41,
.upper_margin = 2,
.lower_margin = 2,
.vsync_len = 10,
将下面这行注释掉
//.lpcsel =((0xCE6) & ~7) | 1<<4, /* lpc3600 control register */
2.在arch/arm/mach-s3c2440/mach-smdk2440.c的smdk2440_devices[]结构体数组中已经有lcd设备
&s3c_device_lcd,
3.配置内核
DeviceDrivers --->
Graphicssupport --->
<*> Supportfor frame buffer devices --->
<*> S3C2410 LCD framebuffer support
[*] Bootup logo --->
[ ] Standard black and white Linux logo
[ ] Standard 16-color Linux logo
[*] Standard 224-color Linux logo (NEW)
4.重新编译内核
将看到LCD显示开机logo
5.解决10分钟后黑屏:修改drivers/char/vt.c
可修改staticint blankinterval = 10*60;
默认为10分钟后LCD背光就自动关闭,当发生中断就会开启,改为0,LCD就常亮。
6.关闭光标:修改/drivers/video/console/softcursor.c
intsoft_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
#if 0
struct fbcon_ops *ops =info->fbcon_par;
unsigned int scan_align =info->pixmap.scan_align - 1;
unsigned int buf_align =info->pixmap.buf_align - 1;
unsigned int i, size, dsize, s_pitch,d_pitch;
struct fb_image *image;
u8 *src, *dst;
if (info->state !=FBINFO_STATE_RUNNING)
return 0;
s_pitch = (cursor->image.width + 7)>> 3;
dsize = s_pitch *cursor->image.height;
if (dsize + sizeof(struct fb_image) !=ops->cursor_size) {
if (ops->cursor_src != NULL)
kfree(ops->cursor_src);
ops->cursor_size = dsize +sizeof(struct fb_image);
ops->cursor_src =kmalloc(ops->cursor_size, GFP_ATOMIC);
if (!ops->cursor_src) {
ops->cursor_size = 0;
return -ENOMEM;
}
}
src = ops->cursor_src + sizeof(structfb_image);
image = (struct fb_image*)ops->cursor_src;
*image = cursor->image;
d_pitch = (s_pitch + scan_align) &~scan_align;
size = d_pitch * image->height +buf_align;
size &= ~buf_align;
dst = fb_get_buffer_offset(info,&info->pixmap, size);
if (cursor->enable) {
switch (cursor->rop) {
case ROP_XOR:
for (i = 0; i < dsize;i++)
src[i] =image->data[i] ^ cursor->mask[i];
break;
case ROP_COPY:
default:
for (i = 0; i < dsize;i++)
src[i] =image->data[i] & cursor->mask[i];
break;
}
} else
memcpy(src, image->data,dsize);
fb_pad_aligned_buffer(dst, d_pitch, src,s_pitch, image->height);
image->data = dst;
info->fbops->fb_imageblit(info,image);
#endif
return 0;
}
六、触摸屏驱动移植
1.在BSP文件加入头文件
#include<plat/ts.h>
2.加入触摸屏数据
staticstruct s3c2410_ts_mach_info hard_s3c2410ts_info = {
.delay = 0xffff,
.oversampling_shift = 2,
.cfg_gpio = s3c24xx_ts_cfg_gpio,
};
3.添加触摸屏和ADC平台设备列表,ADC一定要在TS前面
&s3c_device_adc,
&s3c_device_ts,
4.加入如下函数,这个函数将上面加入的结构体设为触摸屏设备的 s3c_device_ts.dev.platform_data
static void__init smdk2440_machine_init(void)
{
s3c24xx_fb_set_platdata(&smdk2440_fb_info);
s3c_i2c0_set_platdata(NULL);
s3c24xx_mci_set_platdata(&sd_cfg);
s3c24xx_ts_set_platdata(&hard_s3c2410ts_info);
platform_add_devices(smdk2440_devices,ARRAY_SIZE(smdk2440_devices));
smdk_machine_init();
}
5.修改arch/arm/plat-s3c24xx/Kconfig
configS3C2410_SETUP_TS
bool "Touchscreensetup"
6.配置内核
System Type --->
[*] Touchscreensetup
Device Drivers --->
Input device support --->
[*] Touchscreens --->
<*> Samsung S3C2410/generic touchscreen input driver
7.重新编译内核
启动时输出
samsung-tss3c2440-ts: driver attached, registering input device
input: S3C24XXTouchScreen as /class/input/input1
8.编写用户空间测试程序
#include <sys/types.h>
#include<sys/stat.h>
#include<stdio.h>
#include<fcntl.h>
#include<signal.h>
#include<unistd.h>
#include<linux/input.h>
#include<stdlib.h>
#include<string.h>
int fd;
structinput_event event;
voidinput_handle(int signum)
{
if (read(fd, &event, sizeof(structinput_event))< 0) {
perror("read");
}
printf("tv_sec:%d\n",event.time.tv_sec);
printf("tv_usec:%d\n",event.time.tv_usec);
printf("type:%d\n",event.type);
printf("code:%d\n",event.code);
printf("value:%d\n",event.value);
}
int main()
{
int oflags;
fd = open("/dev/event1",O_RDWR, S_IRUSR|S_IWUSR);
if (fd != -1) {
signal(SIGIO, input_handle);
fcntl(fd, F_SETOWN, getpid());
oflags = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, oflags|FASYNC);
while (1) {
sleep(100);
}
}
else
printf("err\n");
}
七、WDT看门狗驱动移植
1.在arch/arm/mach-s3c2440/mach-smdk2440.c已经添加了wdt平台设备列表
&s3c_device_wdt,
2.修改drivers/watchdog/s3c2410_wdt.c第51行启动看门狗
#defineCONFIG_S3C2410_WATCHDOG_ATBOOT (1) // 启动看门狗
#defineCONFIG_S3C2410_WATCHDOG_DEFAULT_TIME (15) //超时值15s
3.配置内核
Device Drivers --->
[*] WatchdogTimer Support --->
<*> S3C2410 Watchdog
4.重新编译内核并下载到开发板,串口输出:
s3c2410_wdt:S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics
s3c2410-wdts3c2410-wdt: >starting watchdog timer
s3c2410-wdts3c2410-wdt: >watchdog active, reset enabled, irq disabled
此时由于没有喂狗,系统启动后过会会自动重启
5.编写喂狗程序feed_wdt.c
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<linux/watchdog.h>
int main()
{
int fd;
if ((fd = open("/dev/watchdog",O_RDONLY))< 0)
{
perror("open");
exit(1);
}
for (;;)
{
ioctl(fd, WDIOC_KEEPALIVE);
sleep(3);
}
close(fd);
return 0;
}
6.交叉编译feed_wdt.c
root@zjh://home/work#arm-linux-gcc -static feed_wdt.c -o feed_wdt
将生成的可执行文件feed_wdt拷贝到根文件系统/bin目录下
root@zjh://home/work#cp feed_wdt rootfs/bin/
7.修改启动脚本文件rootfs/etc/init.d/rcS
#!/bin/sh
#This is thefirst script called by init process
mount -a
mkdir /dev/pts
mount -t devptsdevpts /dev/pts
echo/sbin/mdev>/proc/sys/kernel/hotplug
mdev -s
feed_wdt&
ifconfig lo127.0.0.1
ifconfig eth0192.168.1.100 netmask 255.255.255.0
route add defaultgw 192.168.1.1
八、按键输入子系统移植
1.arch/arm/mach-s3c2440/mach-smdk2440.c加入按键相关platform代码
#include<linux/gpio_keys.h>
#include<linux/input.h>
staticstruct gpio_keys_button tq2440_buttons[] = {
{
.gpio = S3C2410_GPF(1),
.code = KEY_UP,
.desc = "Up",
.active_low = 1,
.wakeup = 0,
},
{
.gpio = S3C2410_GPF(4),
.code = KEY_DOWN,
.desc = "Down",
.active_low = 1,
.wakeup = 0,
},
{
.gpio = S3C2410_GPF(2),
.code = KEY_LEFT,
.desc = "Left",
.active_low = 1,
.wakeup = 0,
},
{
.gpio = S3C2410_GPF(0),
.code = KEY_RIGHT,
.desc = "Right",
.active_low = 1,
.wakeup = 0,
}
};
staticstruct gpio_keys_platform_data tq2440_button_data = {
.buttons = tq2440_buttons,
.nbuttons = ARRAY_SIZE(tq2440_buttons),
};
staticstruct platform_device tq2440_device_button = {
.name ="gpio-keys",
.id =-1,
.dev ={
.platform_data=&tq2440_button_data,
},
};
在smdk2440_devices[]中加入platform设备
&tq2440_device_button,
2.配置内核
Device Drivers --->
Input devicesupport --->
[*] Keyboards --->
<*> GPIO Buttons
3.重新编译内核
4.编写用户空间测试程序gpio_button.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/input.h>
#include <sys/fcntl.h>
int main(int argc, char *argv[])
{
int fd =-1;
int num;
size_t rb;
intversion;
charname[20];
structinput_event ev;
if ((fd =open("/dev/event0", O_RDONLY)) < 0)
{
perror("openerror");
exit(1);
}
if(ioctl(fd, EVIOCGNAME(sizeof(name)-1), name) < 0)
{
perror("getnameerror");
exit(1);
}
//printf("name=%s\n",name);
if(ioctl(fd, EVIOCGVERSION, &version) < 0)
{
perror("getversionerror");
exit(1);
}
//printf("version=0x%x\n",version);
while(1)
{
rb= read(fd, &ev, sizeof(struct input_event));
if(rb < (int)sizeof(struct input_event))
{
perror("readerror");
exit(1);
}
//printf("read%d event\n", (int)(rb/sizeof(struct input_event)));
if(EV_KEY==ev.type)
{
if(1 == ev.value)
printf("key%d is pressed\n", ev.code);
else
printf("key %d isreleassed\n", ev.code);
}
}
close(fd);
return 0;
}
九、SD驱动移植
1.arch/arm/mach-s3c2440/mach-smdk2440.c中添加头文件
#include<linux/mmc/host.h>
#include<plat/mci.h>
2.arch/arm/mach-s3c2440/mach-smdk2440.c中填充如下结构
staticstruct s3c24xx_mci_pdata sd_cfg = {
.no_wprotect = true,
.gpio_detect = S3C2410_GPG(8),
.set_power = NULL,
.ocr_avail = MMC_VDD_32_33 |MMC_VDD_33_34,
};
3.添加如下函数:这个函数将上面添加结构体sd_cfg 设为SD 卡平台设备结构s3c_device_sdi的 platform_data。
static void__init smdk2440_machine_init(void)
{
s3c24xx_fb_set_platdata(&smdk2440_fb_info);
s3c_i2c0_set_platdata(NULL);
s3c24xx_mci_set_platdata(&sd_cfg);
platform_add_devices(smdk2440_devices,ARRAY_SIZE(smdk2440_devices));
smdk_machine_init();
}
4.arch/arm/mach-s3c2440/mach-smdk2440.c plat_device 结构体中加入
&s3c_device_sdi,
5.配置内核支持SD卡
DeviceDrivers --->
<*>MMC/SD/SDIO card support --->
<*> MMC block device driver
[*] Use bounce buffer for simple hosts
<*> Samsung S3C SD/MMC Card Interface support
6.重新编译内核
插入SD卡
[root@tq2440 /]# s3c-sdi s3c2440-sdi:running at 0kHz (requested: 0kHz).
s3c-sdi s3c2440-sdi: running at 400kHz(requested: 400kHz).
s3c-sdi s3c2440-sdi: running at 400kHz(requested: 400kHz).
s3c-sdi s3c2440-sdi: running at 400kHz(requested: 400kHz).
s3c-sdi s3c2440-sdi: running at 400kHz(requested: 400kHz).
s3c-sdi s3c2440-sdi: running at 400kHz(requested: 400kHz).
s3c-sdi s3c2440-sdi: running at 400kHz(requested: 400kHz).
s3c-sdi s3c2440-sdi: running at 400kHz(requested: 400kHz).
s3c-sdi s3c2440-sdi: running at 25000kHz(requested: 25000kHz).
s3c-sdi s3c2440-sdi: running at 25000kHz(requested: 25000kHz).
mmc0: new SDHC card at address e624
mmcblk0: mmc0:e624 SU04G 3.69 GiB
mmcblk0: p1
[root@tq2440 /]# mount /dev/mmcblk0p1/mnt/ 手动挂载SD卡
[root@tq2440 /]# ls /mnt/ 列出SD内容
z.txt
[root@tq2440 /]# umount /mnt/ 卸载SD卡
7.实现自动挂载SD卡
在根文件系统根目录下创建用于挂载SD卡的目录
root@zjh:/home/rootfs#mkdir sddisk
在etc/下创建配置文件mdev.conf
root@zjh:/home/work/rootfs#vi etc/mdev.conf
内容如下
mmcblk[0-9]*p[0-9] 0:0 0660 @(mount -t vfat /dev/$MDEV /sddisk)
mmcblk[0-9]*p[0-9] 0:0 0660 $(umount /sddisk)
更多mdev.conf的设置可参考busybox的docs/mdev.txt文件
十、USB主控制器驱动移植
1.SMDK2440 开发板已经添加了USB主控制器驱动s3c2410-ohci
static struct platform_device*smdk2440_devices[] __initdata = {
&s3c_device_ohci,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
&s3c_device_dm9000,
&s3c_device_rtc,
&s3c_device_sdi,
};
2.配置内核
因为优盘用到了SCSI 命令,所以首先增加 SCSI 支持:
DeviceDrivers --->
SCSI devicesupport --->
<*> SCSIdisk support
添加U盘支持
[*] USB support --->
<*> USB Mass Storage support
3.重新编译内核
插入U盘
[root@tq2440 /]#usb 1-1: new full speed USB device using s3c2410-ohci and address 3
scsi1 :usb-storage 1-1:1.0
scsi 1:0:0:0:Direct-Access Kingston DT 101 G2 PMAP PQ: 0 ANSI: 0 CCS
sd 1:0:0:0:Attached scsi generic sg0 type 0
sd 1:0:0:0: [sda]15646720 512-byte logical blocks: (8.01 GB/7.46 GiB)
sd 1:0:0:0: [sda]Write Protect is off
sd 1:0:0:0: [sda]Assuming drive cache: write through
sd 1:0:0:0: [sda]Assuming drive cache: write through
sda: sda1
sd 1:0:0:0: [sda]Assuming drive cache: write through
sd 1:0:0:0: [sda]Attached SCSI removable disk
[root@tq2440 /]#mount /dev/sda1 /mnt/ 手动挂载U盘
[root@tq2440 /]#ls /mnt/ 列出U盘内容
?? ?????????.doc Image2Lcd.rar
?? ????.txt ?????????20110101.pdf TQ2440_Test_20100607.rar
[root@tq2440 /]#umount /mnt/ 卸载U盘
4.实现U盘自动挂载:修改rootfs/etc/mdev.conf,添加如下内容
sd[a-z]*[0-9] 0:0 0660 @(mount -t vfat/dev/$MDEV /udisk)
sd[a-z]*[0-9] 0:0 0660 $(umount /udisk)
十一、USB摄像头驱动移植
1.Linux-2.6.36内核已经支持万能USB摄像头驱动,只需配置内核即可
DeviceDrivers --->
<*>Multimedia support --->
<*> Video For Linux
[*] Enable Video For Linux API 1 (DEPRECATED)(NEW)
[*] Video capture adapters (NEW) --->
[*] V4L USB devices (NEW) --->
<*> USB Video Class (UVC)
[*] UVC input events device support (NEW)
<*> GSPCA based webcams --->
在GSPCA based webcams中选中你要的驱动或全选
2.重新编译内核,插上USB摄像头
[root@tq2440 /]#usb 1-1: new full speed USB device using s3c2410-ohci and address 3
uvcvideo: FoundUVC 1.00 device Vimicro USB Camera (Altair) (0ac8:3450)
input: VimicroUSB Camera (Altair) as /class/input/input3
[root@tq2440 /]#ll /dev/video0
crw-rw---- 1 root root 81, 0 Jan 1 00:00 /dev/video0
3.自己移植的motion移动图像监控系统效果图
十二、UDA1341声卡驱动移植
1.在arch/arm/mach-s3c2440/mach-smdk2440.c构建UDA1341平台设备
#include<sound/s3c24xx_uda134x.h>
staticstruct 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,
};
staticstruct platform_device s3c24xx_uda134x = {
.name = "s3c24xx_uda134x",
.dev = {
.platform_data = &s3c24xx_uda134x_data,
}
};
在smdk2440_devices[]结构体中加入
&s3c24xx_uda134x,
2.配置内核
DeviceDrivers --->
<*> Soundcard support --->
<*> Advanced Linux Sound Architecture --->
<*> OSS Mixer API
<*> OSS PCM (digital audio) API
[*] Verbose procfs contents
<*> ALSA for SoC audio support --->
<*> SoC Audio for the Samsung S3CXXXX chips
<*> SoC I2S Audio support UDA134X wired to aS3C24XX
3.重新编译,启动开发板
[root@tq2440 /]#ll /dev/controlC0 /dev/pcmC0D0c /dev/pcmC0D0p /dev/timer
crw-rw---- 1 0 0 116, 0 Oct 21 18:14 /dev/controlC0控制设备
crw-rw---- 1 0 0 116, 24 Oct 21 18:14 /dev/pcmC0D0c录音流设备
crw-rw---- 1 0 0 116, 16 Oct 21 18:14 /dev/pcmC0D0p播放流设备
crw-rw---- 1 0 0 116, 33 Oct 21 18:14 /dev/timer定时器设备
4.测试声卡
[root@tq2440 /]#cat /dev/dsp > test.wav 录音
[root@tq2440 /]#cat test.wav > /dev/dsp 放音
5.Madplay播放器移植
1) 准备源码madplay-0.15.2b.tar.gz libmad-0.15.1b.tar.gz libid3tag-0.15.1b.tar.gz zlib-1.2.7.tar.gz
2) 新建目录madplay/install,并将以上源码拷贝到madplay目录,并解压
root@zjh:/home/work# mkdir -pmadplay/install
3) 编译zlib
root@zjh:/home/work/madplay# cd zlib-1.2.7
root@zjh:/home/work/madplay/zlib-1.2.7#./configure --prefix=/home/work/madplay/install/
root@zjh:/home/work/madplay/zlib-1.2.7# viMakefile
19 CC=arm-linux-gcc
30 LDSHARED=arm-linux-gcc
31 CPP=arm-linux-gcc -E
39 AR=arm-linux-ar
41 RANLIB=arm-linux-ranlib
root@zjh:/home/work/madplay/zlib-1.2.7#make
root@zjh:/home/work/madplay/zlib-1.2.7#make install
4) 编译libid3tag
root@zjh:/home/work/madplay/zlib-1.2.7# cd../libid3tag-0.15.1b
root@zjh:/home/work/madplay/libid3tag-0.15.1b#./configure CC=arm-linux-gcc --host=arm-linux --prefix=/home/work/madplay/installCPPFLAGS=-I/home/work/madplay/install/include LDFLAGS=-L/home/work/madplay/install/lib
root@zjh:/home/work/madplay/libid3tag-0.15.1b#make
root@zjh:/home/work/madplay/libid3tag-0.15.1b#make install
5) 编译libmad
root@zjh:/home/work/madplay/libid3tag-0.15.1b# cd../libmad-0.15.1b
root@zjh:/home/work/madplay/libmad-0.15.1b#./configure CC=arm-linux-gcc --host=arm-linux--prefix=/home/work/madplay/installCPPFLAGS=-I/home/work/madplay/install/includeLDFLAGS=-L/home/work/madplay/install/lib
root@zjh:/home/work/madplay/libmad-0.15.1b# make出现错误
cc1: error: unrecognized command line option"-fforce-mem"
错误修改,打开Makefile去掉“-fforce-mem”
129 CFLAGS = -Wall -g -O -fforce-mem-fforce-addr -fthread-jumps
root@zjh:/home/work/madplay/libmad-0.15.1b# make
root@zjh:/home/work/madplay/libmad-0.15.1b# makeinstall
6) 编译madplay
root@zjh:/home/work/madplay/libmad-0.15.1b#cd ../madplay-0.15.2b
root@zjh:/home/work/madplay/madplay-0.15.2b#./configure CC=arm-linux-gcc --host=arm-linux--prefix=/home/work/madplay/install CPPFLAGS=-I/home/work/madplay/install/includeLDFLAGS=-L/home/work/madplay/install/lib
root@zjh:/home/work/madplay/madplay-0.15.2b#make
在 madplay-0.15.2b 目录下生成可执行文件madplay,查看一下需要的动态库
root@zjh:/home/work/madplay/madplay-0.15.2b#arm-linux-readelf -d madplay |grep Shared
0x00000001 (NEEDED) Shared library: [libmad.so.0]
0x00000001 (NEEDED) Shared library:[libid3tag.so.0]
0x00000001 (NEEDED) Shared library:[libz.so.1]
0x00000001 (NEEDED) Shared library:[libm.so.6]
0x00000001 (NEEDED) Shared library:[libc.so.6]
将后两个文件从/usr/lib 拷贝到根文件系统的/usr/lib目录下(先查看,如果
已经有了则不需要),前两个文件是在/madplay/lib/下生成的,把这两个文件也拷
贝到/usr/lib 下。
将 madplay 复制到根文件系统/usr/bin目录下,将一个 MP3 文件也放在某一目
录下,在开发板上执行 madplay 程序
[root@tq2440 /]# madplay x.mp3
MPEG Audio Decoder 0.15.2 (beta) -Copyright (C) 2000-2004 Robert Leslie et al.
Title: ···
Artist: DJ··
Album: ····
十三、NAND FLASH驱动移植
1.修改arch/arm/plat-s3c24xx/common-smdk.c
static structmtd_partition smdk_default_nand_part[] = {
[0]={
.name = "u-boot",
.size = SZ_256K,
.offset = 0,
},
[1]={
.name = "params",
.size = SZ_128K,
.offset = MTDPART_OFS_NXTBLK,
},
[2]={
.name = "kernel",
.size = SZ_1M + SZ_2M,
.offset = MTDPART_OFS_NXTBLK,
},
[3]={
.name = "rootfs",
.size = MTDPART_SIZ_FULL,
.offset = MTDPART_OFS_NXTBLK
}
};
根据NAND FLASH芯片手册修改时序
static structs3c2410_platform_nand smdk_nand_info = {
.tacls = 10,
.twrph0 =20,
.twrph1 =10,
.nr_sets =ARRAY_SIZE(smdk_nand_sets),
.sets =smdk_nand_sets,
};
2.配置内核
root@zjh:/home/work/linux-2.6.36.4#make menuconfig
DeviceDrivers --->
<*>Memory Technology Device (MTD) support --->
[*] MTD partitioning support
<*> Direct char device access to MTD devices
-*- Common interface to block layer for MTD'translation layers'
<*> Caching block device access to MTD devices
<*> NAND Device Support --->
<*> NAND Flash support for Samsung S3C SoCs
[ ] Samsung S3C NAND Hardware ECC
3.制作cramfs文件系统(首先要确保你已经制作好一个根文件系统)
root@zjh:/home/work#mkfs.cramfs rootfs rootfs.cramfs 注:rootfs为根文件系统目录
将rootfs.cramfs拷贝到ftp服务器目录
root@zjh:/home/work#cp rootfs.cramfs /tftpboot/
将rootfs.cramfs固化到NANDFLASH第3个分区(/dev/mtdblock2)
TQ2440 # tftp32000000 rootfs.cramfs
TQ2440 # nanderase 400000 fc00000
TQ2440 # nandwrite 32000000 400000 $(filesize)
4.重新设置u-boot启动参数
TQ2440 # setbootargs root=/dev/mtdblock2 init=/linuxrc console=ttySAC0,115200
TQ2440 # save
5.下载内核uImage到内存
TQ2440 # tftp30000000 uImage
TQ2440 # bootm30000000
………………
………………
Creating 3 MTDpartitions on "NAND 256MiB 3,3V 8-bit":
0x000000000000-0x000000100000: "u-boot"
0x000000100000-0x000000400000: "kernel"
0x000000400000-0x000010000000: "rootfs"
………………
………………
VFS: Mountedroot (cramfs filesystem) readonly on device 31:2.
…………
…………
[root@tq2440/]# cat /proc/mtd
dev: size erasesize name
mtd0: 0010000000020000 "u-boot"
mtd1: 0030000000020000 "kernel"
mtd2: 0fc0000000020000 "rootfs"
十四、移植yaffs文件系统
1、下载yaffs2源码
http://www.aleph1.co.uk/gitweb?p=yaffs2.git;a=summary
2、解压yaffs2源码并给内核打补丁
root@zjh:/home/work# tar -zxvf yaffs2-34292b4.tar.gz
root@zjh:/home/work# cd yaffs2-34292b4
root@zjh:/home/work/yaffs2-34292b4# ./patch-ker.sh c m../linux-2.6.36.4
3、配置内核
File systems --->
[*]Miscellaneous filesystems --->
[*] yaffs2 file system support
4、重新编译内核并烧写uImage到nand
5、设置u-boot启动参数
set bootargs root=/dev/mtdblock3 rootfstype=yaffs2init=/linuxrc console=ttySAC0,115200
set bootcmd nand read 30000000 kernel\;bootm 30000000
6、启动
yaffs: dev is 32505859 name is "mtdblock3"rw
yaffs: passed flags ""
VFS: Mounted root (yaffs2 filesystem) on device 31:3.
Freeing init memory: 120K
Please press Enter to activate this console.
Processing /etc/profile...
Done
[root@tq2440 /]#
十五、ADC驱动移植
1、 在arch/arm/mach-s3c2440/mach-smdk2440.c添加头文件
#include <plat/hwmon.h>
2、 在smdk2440_devices[]数组中加入
&s3c_device_adc,
&s3c_device_hwmon,
其中s3c_device_adc是在arch/arm/plat-s3c24xx/devs.c文件中实现的,s3c_device_hwmon是在arch/arm/plat-samsung/dev-hwmon.c文件中实现的
3、 在smdk2440_machine_init函数中加入设置hwmon平台数据函数:
s3c_hwmon_set_platdata(&tq2440_hwmon_info);
4、 构建HWMON设备平台数据结构:
/* ADC */
struct s3c_hwmon_chcfg ch2 = {
.name ="adc-ch2",
.mult = 3300,
.div = 512,
};
static struct s3c_hwmon_pdata tq2440_hwmon_info__initdata = {
.in[2] =&ch2,
};
TQ2440开发板用到了第2通道
5、 修改arch/arm/plat-samsung/目录下的Kconfig文件:在S3C_DEV_HWMON选项下加入default y,这样是为了编译dev-hwmon.c这个文件
configS3C_DEV_HWMON
bool
default y
help
Compile in platform device definitions for HWMON
6、 配置内核,支持hwmon驱动:
System Type --->
-*- ADCcommon driver support
Device Drivers --->
<*>Hardware Monitoring support --->
<*> S3C24XX/S3C64XX Inbuilt ADC
[*] Include raw channel attributes in sysfs
7、 重新编译make uImage
drivers/hwmon/s3c-hwmon.c:54: error: field 'lock' hasincomplete type
drivers/hwmon/s3c-hwmon.c: In function's3c_hwmon_read_ch':
drivers/hwmon/s3c-hwmon.c:76: error: implicitdeclaration of function 'down_interruptible'
drivers/hwmon/s3c-hwmon.c:83: error: implicitdeclaration of function 'up'
drivers/hwmon/s3c-hwmon.c: In function's3c_hwmon_create_attr':
drivers/hwmon/s3c-hwmon.c:237: error: 'structattribute' has no member named 'owner'
drivers/hwmon/s3c-hwmon.c:255: error: 'structattribute' has no member named 'owner'
drivers/hwmon/s3c-hwmon.c: In function's3c_hwmon_probe':
drivers/hwmon/s3c-hwmon.c:299: error: implicitdeclaration of function 'init_MUTEX'
出错
打开drivers/hwmon/s3c-hwmon.c54行
struct semaphore lock;
可能是没添加头文件,添加头文件
#include <linux/semaphore.h>
重新编译
出错
drivers/hwmon/s3c-hwmon.c: In function's3c_hwmon_create_attr':
drivers/hwmon/s3c-hwmon.c:237: error: 'structattribute' has no member named 'owner'
drivers/hwmon/s3c-hwmon.c:255: error: 'structattribute' has no member named 'owner'
make[2]: *** [drivers/hwmon/s3c-hwmon.o] Error 1
make[1]: *** [drivers/hwmon] Error 2
make: *** [drivers] Error 2
屏蔽237行
//attr->dev_attr.attr.owner = THIS_MODULE;
屏蔽255行
//attr->dev_attr.attr.owner = THIS_MODULE;
重新编译成功
8、 烧写到开发板重启
[root@tq2440 /]# ls /sys/class/hwmon/hwmon0/device/
adc0_raw adc4_raw bus in2_label uevent
adc1_raw adc5_raw driver modalias
adc2_raw adc6_raw hwmon:hwmon0 power
adc3_raw adc7_raw in2_input subsystem
这个目录下有8个名为adcx_raw的文件,分别对应S3C2440的8路ADC
cat /sys/class/hwmon/hwmon0/device/adc2_raw查看通道的AD转换值
查看arch\arm\plat-samsung\include\plat\hwmon.h
/**
*s3c_hwmon_chcfg - channel configuration
* @name: Thename to give this channel.
* @mult:Multiply the ADC value read by this.
* @div: Dividethe value from the ADC by this.
*
* The valueread from the ADC is converted to a value that
* hwmon expects (mV) by result = (value_read * @mult) / @div.
*/
struct s3c_hwmon_chcfg {
const char *name;
unsigned int mult;
unsigned int div;
};
十六、I2C驱动移植(TQ2440的I2C总线挂接的是AT24C02)
1、在arch/arm/mach-s3c2440/mach-smdk2440.c中已经添加了I2C的支持
2、配置内核
Device Drivers --->
<*>I2C support --->
[*] Enable compatibility bits for old user-space
<*> I2C device interface
[*] Autoselect pertinent helper modules
I2CHardware Bus support --->
<*>S3C2410 I2C Driver
3、重新编译内核并烧写到开发板重启
查看设备
[root@tq2440 /]# ll /dev/i2c-0
crw-rw---- 1root root 89, 0 Jan 9 21:44 /dev/i2c-0
十七、DS18B20驱动移植(ds18b20接在S3C2440的GPG14)
1、在arch/arm/mach-s3c2440/mach-smdk2440.c文件中构建DS18B20设备
添加头文件
#include <linux/w1-gpio.h>
#include <plat/gpio-cfg.h>
构建DS18B20设备的平台数据结构:
/* DS18B20 */
static voidw1_enable_external_pullup(int enable)
{
if (enable)
s3c_gpio_setpull(S3C2410_GPG(14),S3C_GPIO_PULL_UP);
else
s3c_gpio_setpull(S3C2410_GPG(14),S3C_GPIO_PULL_NONE);
}
static structw1_gpio_platform_data ds18b20_w1_gpio = {
.pin = S3C2410_GPG(14),
.is_open_drain = 0,
.enable_external_pullup =w1_enable_external_pullup,
};
static structplatform_device tq2440_ds18b20_device = {
.name = "w1-gpio",
.id = -1,
.dev = {
.platform_data = &ds18b20_w1_gpio,
},
};
在smdk2440_devices[]中加入
&tq2440_ds18b20_device
2、配置内核支持w1-gpio和ds18b20驱动
Device Drivers --->
{*}Dallas's 1-wire support --->
1-wireBus Masters --->
<*>GPIO 1-wire busmaster
1- wire Slaves --->
<*> Thermal family implementation
3、重新编译
[root@tq2440 /]# ls sys/devices/w1\ bus\ master/
28-0000032121a3 w1_master_name
bus w1_master_pointer
driver w1_master_pullup
power w1_master_remove
subsystem w1_master_search
uevent w1_master_slave_count
w1_master_add w1_master_slaves
w1_master_attempts w1_master_timeout
w1_master_max_slave_count
这个目录下有一个以“28-”开头的目录,这个就是你的DS18B20设备的目录,28代表你使用的温度传感器是DS18B20,后面接的一串数字和字母是它的ID号(用来识别不同设备,也是独一无二的)
进入这个目录,里面的w1_slave文件就是它的设备文件:
[root@tq2440 28-0000032121a3]# ls
bus id power uevent
driver name subsystem w1_slave
获取温度值:
查看w1_slave设备文件中的内容,便可得到温度值,执行命令cat w1_slave
[root@tq2440 28-0000032121a3]# cat w1_slave
fe 00 4b 46 7f ff 02 10 8a : crc=8a YES
fe 00 4b 46 7f ff 02 10 8a t=15875
“t=”后面的数字就是温度值,要在千位的后面加上小数点,此时温度为:15.875摄氏度