TQ2440内核配置和编译及相关测试方法,(很全)

来源:互联网 发布:淘宝售后客服招聘 编辑:程序博客网 时间:2024/05/15 17:47
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 
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摄氏度 
0 0
原创粉丝点击