2.6.32.2 linux

2012-10-18 21:37:39 changqiang08 阅读数 1815

目的:(1)编译linux-2.6.32.2-mini2440-20110413.tar.gz

工具:ubuntu11.10

问题及解决办法:

(1),在虚拟机中的共享文件夹中解压linux-2.6.32.2-mini2440-20110413.tar.gz,结果提示下面的错误。

tar: linux-2.6.32.2/arch/microblaze/boot/dts/system.dts:无法创建到 “../../platform/generic/system.dts” 的符号连接: 不支持的操作

网友提醒,不要在共享目录下解压

http://bbs.witech.com.cn/thread-16353-1-1.html

(2)在执行命令

         cp config_mini2440_w35 .config
         make menuconfig时,出现下面情况:

** Unable to find the ncurses libraries or the
*** required header files.

*** 'make menuconfig' requires the ncurses libraries.

 *** Install ncurses (ncurses-devel) and try again.

解决办法:
sudo apt-get insatll ncurses-dev

2013-08-17 22:54:12 anakin4 阅读数 450
说明:解压内核源代码(linux-2.6.32.2 开头的tgz 压缩文件)可以找到如下驱动,mini2440
提供基于linux-2.6.32.2 内核100%完全可以使用的驱动源代码,绝无库文件,敬请放心使用。
(1)DM9000 网卡驱动
Linux-2.6.32.2/drivers/net/dm9000.c
(2)串口(包括三个串口驱动0,1,2,对应设备名/dev/ttySAC0,1,2)
Linux-2.6.32.2/drivers/serial/s3c2440.c
(3)实时时钟RTC 驱动
Linux-2.6.32.2/drivers/rtc/rtc-s3c.c
(4)LED 驱动
Linux-2.6.32.2/drivers/char/mini2440_leds.c
(5)按键驱动
Linux-2.6.32.2/drivers/char/mini2440_buttons.c
(6)触摸屏驱动
Linux-2.6.32.2/drivers/input/touchscreen/s3c2410_ts.c
(7)yaffs2 文件系统源代码目录
Linux-2.6.32.2/fs/yaffs2
(8)USB 鼠标、键盘源代码
Linux-2.6.32.2/drivers/usb/hid
(9)SD/MMC 卡驱动源代码目录(支持高速最大容量32G SD 卡)
Linux-2.6.32.2/drivers/mmc
(10)Nand Flash 驱动
Linux-2.6.32.2/drivers/mtd/nand
(11)UDA1341 音频驱动目录
Linux-2.6.32.2/sound/soc/s3c24xx
(12)LCD 驱动
Linux-2.6.32.2/drivers/video/s3c2410fb.c
(13)优盘支持驱动
Linux-2.6.32.2/drivers/usb/storage
(14)万能USB 摄像头驱动
Linux-2.6.32.2/drivers/media/video/gspca
(15)I2C-EEPROM 驱动
inux-2.6.32.2/drivers/i2c
(16)背光驱动
Linux-2.6.32.2/drivers/video/mini2440_backlight.c
(17)PWM 控制蜂鸣器驱动
Linux-2.6.32.2/drivers/char/mini2440_pwm.c
(18)看门狗驱动
Linux-2.6.32.2/drivers/watchdog/s3c2410_wdt.c
(19)AD 转换驱动
Linux-2.6.32.2/drivers/char/mini2440_ad.c
(20)CMOS 摄像头驱动
Linux-2.6.32.2/drivers/media/video/s3c2440camif.c
(21)USB 无线网卡驱动(型号:TL-WN321G+)
Linux-2.6.32.2/drivers/net/wireless/rt2x00
(22)USB 转串口驱动

Linux-2.6.32.2/drivers/usb/serial/pl2302.c


http://xl028.blog.163.com/blog/static/199730242201232584331318/

2010-01-02 17:45:00 cxf17 阅读数 970

硬件:s3c2410
内核:2.6.32.2
交叉编译器 :3.4.1
       这篇文档只记录内核的移植,相应的bios和根文件系统请自己准备,网上的资料很多的。等以后我也会把我自己做的根文件系统的记录整理一下,不多说了,进入正题
       第一,修改bios里的启动参数,将控制台改为ttySAC0(2.4下为ttyS0),生成一个新的bios。
       第二,下载内核源码linux-2.6.32.2.tar.bz2,并且准备一个yaffs的补丁cvs-root.tar.gz
       第三,开始移植
           (1)解压缩内核和yaffs补丁
               假定现在所在目录为/home/cxf/
               tar -jxvf linux-2.6.32.2.tar.bz2
               tar -zxvf cvs-root.tar.gz
           (2)将补丁打上
                cd cvs/yaffs2
               ./patch-ker.sh c /home/cxf/linux-2.6.32.2/
           (3)修改内核Makefile
               cd /home/cxf/linux-2.6.32.2
               修改Makefile,183和184行
               改为
               ARCH        ?= arm
               CROSS_COMPILE    ?= /usr/local/arm/3.4.1/bin/arm-linux-
          (4)修改内核源码
               修改nand flash分区使之与bios中设置一致
               vi linux-2.6.32.2/arch/arm/plat-s3c24xx/common-smdk.c,其中有一个结构体 smdk_default_nand_part[],即flash分区。结构体 smdk_nand_sets中的.nr_chips成员表示分区的数量,如实赋值即可
               去掉ECC校验
vi driver/mtd/nand/s3c2410.c
             查找关键字NAND_ECC_SOFT,将其改为NAND_ECC_NONE
          (5)将默认的配置文件copy到内核的根目录下
               cp arch/arm/configs/s3c2410-defconfig .config
          (6)配置内核
              make menuconfig 进入配置界面
                 Load an Alternate Configuration File 
                 输入.config
              Boot options  --->
                         (0x0) Compressed ROM boot loader BSS address //此项下面
                       │noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0,115200
              File systems  --->//这几个选项去掉吧,没什么用,减小内核体积
                         <> Second extended fs support
                         <> Ext3 journalling file system support
                         <> The Extended 4 (ext4) filesystem
                         [*] Miscellaneous filesystems  ---> //选上这个
                         <*>   YAFFS2 file system support
              Device Drivers  ---> //选上
                        <*> Memory Technology Device (MTD) support  --->           
                                    [*]   MTD partitioning support
       说明:这个只是最基本的配置,你可以自己再裁剪以下,去掉自己不需要的,使生成的内核文件更小一些
         保存退出,make即可生成zImage,在arch/arm/boot目录下
将生成的内核烧进板子,就可以跑起来了

2011-11-16 21:20:13 HL5654 阅读数 1289

Linux-2.6.32.2内核在mini2440上的移植(七)---添加ADC驱动  

【2】在内核中添加ADC 驱动

Linux-2.6.32.2 内核并没有提供支持S3C2440 的ADC 驱动程序,由于《移植开发实战指南》中ADC部分代码在实际测试中始终输出-1,而无法通过测试,于是结合博主黄刚嵌入式Linux之我行——S3C2440上ADC驱动实例开发讲解的ADC驱动程序作了下修改,经过修改后有一个好处是方便地通过s3c24xx-adc.h文件中提供的宏修改通道获取采样数据,该头文件的代码也在drivers/char目录下内容为:

#ifndef _S3C2410_ADC_H_
#define _S3C2410_ADC_H_

#define ADC_WRITE(ch, prescale) ((ch)<<16|(prescale))
#define ADC_WRITE_GETCH(data) (((data)>>16)&0x7)
#define ADC_WRITE_GETPRE(data) ((data)&0xff)

#endif /* _S3C2410_ADC_H_ */

驱动程序的文件名为:mini2440_adc.c位于drivers/char 目录下。由上述内容可知,ADC 驱动和触摸屏驱动若想共存,就必须解决共享“A/D 转换器”资源这个问题,因此在ADC 驱动程序中声明了一个全局的“ADC_LOCK”信号量,ADC 驱动程序的内容和注解如下:

#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/serio.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <mach/regs-clock.h>
#include <plat/regs-timer.h>
#include <plat/regs-adc.h>
#include <mach/regs-gpio.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>

//;自己定义的头文件,因原生内核并没有包含
#include "s3c24xx-adc.h"

#undef DEBUG
//#define DEBUG
#ifdef DEBUG
#define DPRINTK(x...) {printk(__FUNCTION__"(%d): ",__LINE__);printk(##x);}
#else
#define DPRINTK(x...) (void)(0)
#endif

//;定义ADC 转换设备名称,将出现在/dev/adc
#define DEVICE_NAME "adc"

static void __iomem *adc_base;/*定义了一个用来保存经过虚拟映射后的内存地址*/

//;定义ADC 设备结构
typedef struct {
 wait_queue_head_t wait;
 int channel;
 int prescale;
}ADC_DEV;
static ADC_DEV adcdev;

//;声明全局信号量,以便和触摸屏驱动程序共享A/D 转换器
DECLARE_MUTEX(ADC_LOCK);

//;ADC驱动是否拥有A/D 转换器资源的状态变量
//static volatile int OwnADC = 0;

/*用于标识AD转换后的数据是否可以读取,0表示不可读取*/
static volatile int ev_adc = 0;

/*用于保存读取的AD转换后的值,该值在ADC中断中读取*/
static int adc_data;

/*保存从平台时钟队列中获取ADC的时钟*/
static struct clk *adc_clk;

//;定义ADC 相关的寄存器
#define ADCCON (*(volatile unsigned long *)(adc_base + S3C2410_ADCCON)) //ADC control
#define ADCTSC (*(volatile unsigned long *)(adc_base + S3C2410_ADCTSC)) //ADC touch screen control
#define ADCDLY (*(volatile unsigned long *)(adc_base + S3C2410_ADCDLY)) //ADC start or IntervalDelay
#define ADCDAT0 (*(volatile unsigned long *)(adc_base + S3C2410_ADCDAT0)) //ADC conversion data 0
#define ADCDAT1 (*(volatile unsigned long *)(adc_base + S3C2410_ADCDAT1)) //ADC conversion data 1
#define ADCUPDN (*(volatile unsigned long *)(adc_base + 0x14)) //Stylus Up/Down interrupt status
#define PRESCALE_DIS (0 << 14)
#define PRESCALE_EN (1 << 14)
#define PRSCVL(x) ((x) << 6)
#define ADC_INPUT(x) ((x) << 3)
#define ADC_START (1 << 0)
#define ADC_ENDCVT (1 << 15)

//;定义“开启AD 输入”宏,因为比较简单,故没有做成函数

//#define START_ADC_AIN(ch, prescale)
#define start_adc(ch, prescale) \
do{ \
 ADCCON = PRESCALE_EN | PRSCVL(prescale) | ADC_INPUT((ch)) ; \
 ADCCON |= ADC_START; \
}while(0)
/*设置ADC控制寄存器,开启AD转换*/
/*static void start_adc(int ch,int prescale)
{
    unsigned int tmp;

    tmp = PRESCALE_EN | PRSCVL(prescale) | ADC_INPUT(ch);//(1 << 14)|(255 << 6)|(0 << 3);// 0 1 00000011 000 0 0 0
 
//此处writl()的原型是void writel(u32 b, volatile void __iomem *addr),addr是经过地址重映射后的地址
    writel(tmp, ADCCON); //AD预分频器使能、模拟输入通道设为AIN0

    tmp = readl(ADCCON);
    tmp = tmp | ADC_START;
//(1 << 0);   // 0 1 00000011 000 0 0 1
    writel(tmp, ADCCON);  
//AD转换开始
}
问题:此函数被调用时为什么地址映射错误?答案应该需要使用专用的函数iowrite32操作。
*/

//;ADC 中断处理函数
static irqreturn_t adc_irq(int irq, void *dev_id)
{
 //;如果ADC 驱动拥有“A/D 转换器”资源,则从ADC 寄存器读取转换结果
 if (!ev_adc)
 {
  /*读取AD转换后的值保存到全局变量adc_data中,S3C2410_ADCDAT0定义在regs-adc.h中,
           这里为什么要与上一个0x3ff,很简单,因为AD转换后的数据是保存在ADCDAT0的第0-9位,
           所以与上0x3ff(即:1111111111)后就得到第0-9位的数据,多余的位就都为0*/
  adc_data = ADCDAT0 & 0x3ff;

  /*将可读标识为1,并唤醒等待队列*/
  ev_adc = 1;
  wake_up_interruptible(&adcdev.wait);
 }
 return IRQ_HANDLED;
}

//;ADC 读函数,一般对应于用户层/应用层的设备读函数(read)
static ssize_t adc_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
{
 
 /*试着获取信号量(即:加锁)*/
 if (down_trylock(&ADC_LOCK))
 {
  return -EBUSY;
 }
 if(!ev_adc)
/*表示还没有AD转换后的数据,不可读取*/
     {
      if(filp->f_flags & O_NONBLOCK)
         {
             
/*应用程序若采用非阻塞方式读取则返回错误*/
         return -EAGAIN;
         }
      else
/*以阻塞方式进行读取*/
         {
             
 /*设置ADC控制寄存器,开启AD转换*/
         start_adc(adcdev.channel, adcdev.prescale);

              /*使等待队列进入睡眠*/
         wait_event_interruptible(adcdev.wait, ev_adc);
         }
     }
 /*能到这里就表示已有AD转换后的数据,则标识清0,给下一次读做判断用*/
   ev_adc = 0;

     /*将读取到的AD转换后的值发往到上层应用程序*/
   copy_to_user(buffer, (char *)&adc_data, sizeof(adc_data));

     /*释放获取的信号量(即:解锁)*/
   up(&ADC_LOCK);

   return sizeof(adc_data);
 
}

//;打开ADC设备的函数,一般对应于用户态程序的open
static int adc_open(struct inode *inode, struct file *filp)
{
 int ret; 
 /* normal ADC */
 ADCTSC = 0;
 //;初始化中断队列
 init_waitqueue_head(&(adcdev.wait));
 adcdev.channel=0;//;缺省通道为“0”
 adcdev.prescale=0xff;
 /* 申请ADC中断服务,这里使用的是共享中断:IRQF_SHARED,为什么要使用共享中断,因为在触摸屏驱动中
      也使用了这个中断号。中断服务程序为:adc_irq在下面实现,IRQ_ADC是ADC的中断号,这里注意:
      申请中断函数的最后一个参数一定不能为NULL,否则中断申请会失败,这里传入的是ADC_DEV类型的变量*/
 ret = request_irq(IRQ_ADC, adc_irq, IRQF_SHARED, DEVICE_NAME, &adcdev);
 if (ret)
     {
        
   /*错误处理*/
        printk(KERN_ERR "IRQ%d error %d\n", IRQ_ADC, ret);
        return -EINVAL;
     }

 DPRINTK( "adc opened\n");
   return 0;

}
static int adc_release(struct inode *inode, struct file *filp)
{
 DPRINTK( "adc closed\n");
 return 0;
}
static struct file_operations dev_fops = {
 owner: THIS_MODULE,
 open: adc_open,
 read: adc_read,
 release: adc_release,
};
static struct miscdevice adc_miscdev = {
 .minor = MISC_DYNAMIC_MINOR,
 .name = DEVICE_NAME,
 .fops = &dev_fops,
};
static int __init dev_init(void)
{
 int ret;
 /*  1,从平台时钟队列中获取ADC的时钟,这里为什么要取得这个时钟,因为ADC的转换频率跟时钟有关。
     系统的一些时钟定义在arch/arm/plat-s3c24xx/s3c2410-clock.c中*/
 adc_clk = clk_get(NULL, "adc");
 if (!adc_clk) {
  printk(KERN_ERR "failed to get adc clock source\n");
  return -ENOENT;
 }
 /*时钟获取后要使能后才可以使用,clk_enable定义在arch/arm/plat-s3c/clock.c中*/
 clk_enable(adc_clk);

 /*  2,将ADC的IO端口占用的这段IO空间映射到内存的虚拟地址,ioremap定义在io.h中。
      注意:IO空间要映射后才能使用,以后对虚拟地址的操作就是对IO空间的操作,
   S3C2410_PA_ADC是ADC控制器的基地址,定义在mach-s3c2410/include/mach/map.h中,0x20是虚拟地址长度大小*/
 adc_base=ioremap(S3C2410_PA_ADC,0x20);
 if (adc_base == NULL) {
  printk(KERN_ERR "Failed to remap register block\n");
  ret = -EINVAL;
      goto err_noclk;
 }

 /*   3,把看ADC注册成为misc设备,misc_register定义在miscdevice.h中
   adc_miscdev结构体定义及内部接口函数在第2步中讲,MISC_DYNAMIC_MINOR是次设备号,定义在miscdevice.h中*/
   ret = misc_register(&adc_miscdev);
   if (ret)
     {
      
   /*错误处理*/
      printk(KERN_ERR "Cannot register miscdev on minor=%d (%d)\n", MISC_DYNAMIC_MINOR, ret);
      goto err_nomap;
     }
 
   printk(DEVICE_NAME "\tinitialized!\n");
 
 return 0;
 
//以下是上面错误处理的跳转点
err_noclk:
   clk_disable(adc_clk);
   clk_put(adc_clk);

err_nomap:
   iounmap(adc_base);

   return ret;

}

static void __exit dev_exit(void)
{
 
 free_irq(IRQ_ADC, &adcdev);
//;释放中断
 iounmap(adc_base); 
/*释放虚拟地址映射空间*/
 if (adc_clk) 
/*屏蔽和销毁时钟*/
 {
  clk_disable(adc_clk);
  clk_put(adc_clk);
  adc_clk = NULL;
 }
 misc_deregister(&adc_miscdev);
}
//;导出信号量“ADC_LOCK”,以便触摸屏驱动使用
EXPORT_SYMBOL(ADC_LOCK);
module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("singleboy");
MODULE_DESCRIPTION("Mini2440 ADC Driver");

说明:杂项设备(misc device)
杂项设备也是在嵌入式系统中用得比较多的一种设备驱动。在 Linux 内核的include/linux 目录下有Miscdevice.h 文件,要把自己定义的misc device 从设备定义在这里。其实是因为这些字符设备不符合预先确定的字符设备范畴,所有这些设备采用主编号10,一起归于misc device,其实misc_register 就是用主标号10 调用register_chrdev()的。也就是说,misc设备其实也就是特殊的字符设备。

然后打开drivers/char/Makefile 文件,在大概24 行加入ADC 驱动程序目标模块

obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o
obj-$(CONFIG_C2PORT)  += c2port/
obj-$(CONFIG_MINI2440_ADC) += mini2440_adc.o
obj-y    += eeprom/
obj-y    += cb710/

再打开drivers/char/Kconfig 文件,定位到16行附近,加入ADC 驱动配置选项:

menuconfig MISC_DEVICES
 bool "Misc devices"
 default y
 ---help---
   Say Y here to get to see options for device drivers from various
   different categories. This option alone does not add any kernel code.

   If you say N, all options in this submenu will be skipped and disabled.

if MISC_DEVICES

config MINI2440_ADC
 bool "ADC driver for FriendlyARM Mini2440 development boards"
 depends on MACH_MINI2440
 default y if MACH_MINI2440
 help
  this is ADC driver for FriendlyARM Mini2440 development boards
  Notes: the touch-screen-driver required this option

config ATMEL_PWM
 tristate "Atmel AT32/AT91 PWM support"
 depends on AVR32 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9
 help
   This option enables device driver support for the PWM channels
   on certain Atmel processors.  Pulse Width Modulation is used for
   purposes including software controlled power-efficient backlights
   on LCD displays, motor control, and waveform generation.

这样,我们就在内核中添加了ADC 驱动。

【3】确认配置选项

现在内核源代码目录的命令行执行:make menuconfig,依次选择如下子菜单项,找到刚刚添加的ADC 驱动配置选项:
Device Drivers --->
      [*] Misc devices  --->  

如图所示,按空格键选中 ADC 配置选项

Linux-2.6.32.2内核在mini2440上的移植(八)---添加ADC驱动 - singleboy - singleboy的博客

 

 然后退出保存所选配置, 在命令行执行: make zImage , 将会生成arch/arm/boot/zImage,

brd: module loaded
adc     initialized!
S3C24XX NAND Driver, (c) 2004 Simtec Electronics

... ...

说明ADC设备加载成功。

 “adc-test” 测试程序已经集成到我们的文件系统中, 因此在开发板的命令行终端输入:adc-test,旋转开发板上的 W1可调电阻,可以看到 ADC 转换的结果也在变动,按下触摸屏时,会输出“-1” ,这和我们在驱动程序中设置的结果是一样的,如图:

 

接下来,将进行触摸屏驱动移植

 

2012-09-10 15:38:21 taozi343805436 阅读数 1862

1.获取内核移植源码

http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.32.2.tar.bz2

2.解压内核源码

(1).bzip2 -d linux-2.6.32.2.tar.bz2

(2).tar -xvf  linux-2.6.32.2.tar

3.修改总目录下的Makefile

原:

export KBUILD_BUILDHOST := $(SUBARCH)
ARCH ?= $(SUBARCH)
CROSS_COMPILE ?=


改为
export KBUILD_BUILDHOST := $(SUBARCH)
ARCH ?= arm
CROSS_COMPILE ?= arm-linux-
其中,ARCH 是指定目标平台为 arm, CROSS_COMPILE 是指定交叉编译器,这里指定的是系统默认的交叉编译器,如要使用其它的,则要把编译器的全路径在这里写出。

4.测试一下linux编译是否能通过

 #make s3c2410_defconfig ;使用缺省内核配置文件,s3c2410_defconfig 是 SMDK2440 的缺省配置文件
 #make ;编译时间较长

5.克隆建立自己的平台

5.1 linux-2.6.32.2/arch/arm/mach-s3c2440 目 录 下 有 个mach-mini2440.c 文件,它其实就是国外爱好者为 mini2440 移植添加的主要内容了,但我们不需要,直接删除。

5.2 将 linux-2.6.32.2/arch/arm/mach-s3c2440/目录下的 mach-smdk2440.c 复制一份。命名为mach-mini2440.c , 找 到 MACHINE_START(S3C2440, "SMDK2440") , 修 改 为
MACHINE_START(MINI2440, "FriendlyARM Mini2440 development board")

5.3修改时钟源频率

mach-mini2440.c( 就 是 我 们 刚 刚 通 过 复 制mach-smdk2440.c 得到的)的第 160 行 static void __init smdk2440_map_io(void)函数中,把其中的 16934400(代表SMDK2440 目标板上的晶振是 16.9344MHz)改为 mini2440 开发板上实际使用的 12000000(代表 mini2440 开发板上的晶振 12MHz,元器件标号为 X2)

因为我们要制作自己的 mini2440 平台体系,因此把 mach-mini2440.c 中所有的smdk2440 字样改为 mini2440,可以使用批处理命令修改,在 vim 的命令模式下输入:
%s/smdk2440/mini2440/g
上面这句的意思是:把所有和“smdk2440”匹配的字符串全部替换为“mini2440”,前面的“%s“代表字符串匹配,最后的“g”代表 global,是全局的意思。
除此之外,还有一个地方需要改动,在 mini2440_machine_init(void)函数中,把smdk_machine_init()函数调用注释掉,因为我们后面会编写自己的初始化函数,不需要调用smdk2440 原来的。

6.在 Linux 源代码根目录下执行
#make mini2440_defconfig ;使用 Linux 官方自带的 mini2440 配置
#make zImage ;编译内核,时间较长,最后会生成 zImage
重新编译并把生成的内核文件 zImage(位于 arch/arm/boot 目录)下到板子中,可以看到内核已经可以正常启动了。