Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1858186
  • 博文数量: 473
  • 博客积分: 13997
  • 博客等级: 上将
  • 技术积分: 5953
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-22 11:52
文章分类

全部博文(473)

文章存档

2014年(8)

2013年(38)

2012年(95)

2011年(181)

2010年(151)

分类: LINUX

2011-07-18 17:18:24

将linux-2.6.24.tar.bz2解压,得到文件夹linux-2.6.24
================================================================
第1阶段
================================================================
1)、将linux-2.6.24/Makefile下的
ARCH  ?= $(SUBARCH)
CROSS_COMPILE ?=
改为
ARCH  ?= arm
CROSS_COMPILE ?= /usr/crosstool/gcc-3.4.5-glibc-2.3.6/arm-linux/bin/arm-linux-
并保存
2)、在终端上将路径切换到linux-2.6.24,输入命令make gconfig(图形化配置)
在弹出的对话框中单击load按钮。在弹出的对话框中选择arch/--->arm/--->configs/--->s3c2410_defconfig,之后点击确定。
关闭配置。
3)、输入命令 make zImage,等待一段时间即可生成zImage镜象,放在:arch/arm/boot/zImage
4)、要用u-boot来引导linux内核,需要一个专门的工具来对zImage镜象进行包装,这个工具在u-boot的源码里面已提供,即/u-boot-1.3.3/tools/mkimage
将这个文件copy到/usr/bin目录下。
5)、
(1)如果我们没用mkimage对内核进行处理的话,那直接把内核下载到0x30008000再运行就行,内核会自解压运行(不过内核运行需要一个tag来传递参数,而这个tag建议是由bootloader提供的,在u-boot下默认是由bootm命令建立的)。

(2)如果使用mkimage生成内核镜像文件的话,会在内核的前头加上了64byte的信息,供建立tag之用。bootm命令会首先判断bootm xxxx 这个指定的地址xxxx是否与-a指定的加载地址相同。
a、如果不同的话会从这个地址开始提取出这个64byte的头部,对其进行分析,然后把去掉头部的内核复制到-a指定的load地址中去运行之
b、如果相同的话那就让其原封不同的放在那,但-e指定的入口地址会推后64byte,以跳过这64byte的头部。

6)、我们仅以5.2.b的情况进行说明,将终端路径切换到 ... /linux-2.6.24/arch/arm/boot/uImage 在命令行下输入命令:
#mkimage -n 'linux-2.6.24' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008040 -d zImage zImage.img
会在当前目录下生成zImage.img。

7)、此时可通过串口将uImage.img下载到0x30008000,然后bootm,即可运行内核。在u-boot下载内核及运行具体方法如下:
1、# loadb 30008000
2、用ckermit发送文件的方法:
    按下ctrl + \,再按c切换到kermit输入命令 send .../linux-2.6.24/arch/arm/boot/uImage.img,等待发送完毕。
3、# bootm 30008000
如正常即可将内核跑起来。
8)、也可将arch/arm/boot/Makefile中的
quiet_cmd_uimage = UIMAGE  $@
      cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \
下一行修改,结果为:
quiet_cmd_uimage = UIMAGE  $@
      cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \
     -C none -a 0x30008000 -e 0x30008040 \
     -n 'Linux-$(KERNELRELEASE)' -d $< $@
以后,在编译时,可用$make uImage来生成u-boot引导的内核,即上文所说的zImage.img。

================================================================
第2阶段
================================================================
1)、除了可以用串口下载内核镜象之外,在网口己通的情况下,也可用tftp来下载内核镜象,具体在FC7下如何安装和设置tftp服务,可查看邮箱的记载。
安装配置完成后,需要将zImage.img复制到tftp服务的根目录(最好不要在root目录下)。另外记得打开防火墙udp 69 端口。
2)、EDUKIT2410 # tftp 30008000 zImage.img。等待镜象下载完成。
3)、bootm 30008000
如正常 内核可跑起来。
================================================================
第3阶段
================================================================
内核默认使用uart0,如果u-boot使用uart1即第二个串口,如果仅修改引导参数是不能正常打印引动信息的,需要修改对应内核里配置信息:
System Type -->
S3C UART to use for low-level messages-->S3C_LOWLEVEL_UART_PORT 值设为1表示从uart1打印启动信息。
下面是说明:
Choice of which UART port to use for the low-level messages,
such as the `Uncompressing...` at start time. The value of
this configuration should be between zero and two. The port
must have been initialised by the boot-loader before use.
保存配置并重新编译,这样内核uImage可通过u-boot自动下载到开发板上运行,并可看到内核启动信息,直到挂载文件系统错误,因为没有任何
文件系统可用。
================================================================
第4阶段 Mini2410核心板上的DM9000A驱动移植
================================================================
1)、在linux-2.6.24/arch/arm/mach-s3c2410/devs.c 中添加
#include   // add by xionggang
并添加
/* DM9000 resource, add by xionggang */
static struct resource eduk_dm9000_resource[] = {
 [0]= {
  .start = 0x10000000,  // this is based on Mini2410
  .end   = 0x10000000,
  .flags  = IORESOURCE_MEM,
 },
 [1]={
  .start = 0x10000002,
  .end   = 0x10000002,
  .flags = IORESOURCE_MEM,
 },
 [2]={
  .start = IRQ_EINT3,
  .end   = IRQ_EINT3,
  .flags = IORESOURCE_IRQ,
 }
};

static struct dm9000_plat_data eduk_dm9000_platdata ={
 .flags = DM9000_PLATF_16BITONLY,//work in 16bit mode
};

struct platform_device eduk_dm9000_device = {
 .name = "dm9000",
 .id = -1,
 .num_resources = 3,
 .resource = eduk_dm9000_resource,
 .dev = {
 .platform_data = &eduk_dm9000_platdata,
 }
};
EXPORT_SYMBOL(eduk_dm9000_device);
2)、在linux-2.6.24/include/asm-arm/plat-s3c24xx/devs.h 中声明平台设备 eduk_dm9000_device ,在适当位置添加以下内容:
extern struct platform_device eduk_dm9000_device;  // add by xionggang
3)、在linux-2.6.24/arch/arm/mach-s3c2410/mach-smdk2410.c中将eduk_dm9000_device添加到平台设备列表中:
static struct platform_device *smdk2410_devices[] __initdata = {
 &s3c_device_usb,
 &s3c_device_lcd,
 &s3c_device_wdt,
 &s3c_device_i2c,
 &s3c_device_iis,
 &eduk_dm9000_device, // add by xionggang
};
下面主要是设置MAC地址和中断
GPFCON(56000050)GPF3[7:6]置10,功能设置为EINT3。这可以用函数实现:s3c2410_gpio_cfgpin(S3C2410_GPF3, S3C2410_GPF3_EINT3);  
EXTINT0(56000088)[14:12]置0 低电平触发中断 (复位默认为全0,可能不必设)
INTMASK (4A000008) [3] 置0 使能EINT3。
4)、在linux-2.6.24/drivers/net/dm9000.c中添加头文件:
#include   // add by xionggang
在代码部分上面添加:
/* add by xionggang ,dm9000 interrupt */
static char net_mac_addr[]={0x00,0xe0,0x3d,0xf4,0xdd,0xf7}; // MAC
static void *extint0, *intmsk; 
#define EXTINT0          (0x56000088) // 外部中断方式
#define INTMSK           (0x4A000008) // 中断屏蔽
5)、在当前文件中的
 /* Set Node Address */
 for (i = 0; i < 6; i++)
  ndev->dev_addr[i] = db->srom[i];
的后面
 if (!is_valid_ether_addr(ndev->dev_addr)) {
  /* try reading from mac */

  for (i = 0; i < 6; i++)
   ndev->dev_addr[i] = ior(db, i+DM9000_PAR);
 }
的前面
加上以下内容:
/*********** add by xionggang ********/
 for(i=0;i<6;i++){
  ndev->dev_addr[i]=net_mac_addr[i];
 }
 extint0=ioremap_nocache(EXTINT0,4);// 
 intmsk=ioremap_nocache(INTMSK,4);   
 s3c2410_gpio_cfgpin(S3C2410_GPF3, S3C2410_GPF3_EINT3);  
 writel(readl(extint0)&0xffff8fff,extint0); // eint3 low level 
 writel(readl(intmsk)&(~(1<<3)),intmsk); //     
 iounmap(intmsk);
 iounmap(extint0);
/******************end **************/
到此以太网移植源码部分修改完毕,在配置内核时需要选中DM9000驱动,重新编译之后,就可通过以下启动参数来挂载nfs文件系统了:
root=/dev/nfs rw nfsroot="192".168.2.80:/xgnfs ip="192".168.2.199:192.168.2.80:192.168.2.1:255.255.255.0:edukit-iv:eth0:off console="ttySAC1",115200 init="/linuxrc" noinitrd
致此,核心板DM9000A驱动移植结束,运行效果很好,不出现有些像严重丢包,不能下大文件,不能通过交换机的情况。通过交换机一样工作很好,没有丢包现象。

================================================================
第5阶段 主板上的DM9000A驱动移植,参考核心板上DM9000A的移植,应该有多种方法可实现。这里采用最简单的方法。
由于主板上DM9000A采用CPLD扩展IO来控制,其基址为0x20000000;中断也由CPLD控制,CPLD先把中断送给中断线
EINT9,再把EINT9送给EINT8_23中断。这里要注意将EINT9设置为边沿触发中断。如果是电平触发,将会一值中断。另外
CPLD可以不做清除中断处理。
移植重点在于中断处理,地址只需作更改即可,对于中断,采用的方法是在DM9000中断处理函数dm9000_interrupt中对
子中断进行判断,因为EINT8_23中断的产生并不一定是DM9000产生,也可能由主板上KEY等产生。在第4步中断初始化时
只将CPLD的net中断打开,其它中断全部关闭,但是由于未知原因,即使这样做,CPLD可能会产生莫名的中断,此时CPLD
中断状态寄存器值一般为0xCE,为此,在进入DM9000中断服务子程序的最前面,需要做判断,即检查CPLD中断状态寄存器的最高位
是否为0,如果非0,则应打印相关信息后,退出中断,不执行DM9000的相关工作。另外在读CPLD状态寄存器的时候,需要使用
到物理地址0x22200000,由于这个地址并没有加入到内核地址映射表中,需要人为加入,有两种方法,一种是静态映射,一种是动
态映射:静态映射即是在mach-smdk2410.c的struct map_desc smdk2410_iodesc[] __initdata数组中加入以下映射:
static struct map_desc smdk2410_iodesc[] __initdata = {
  /* nothing here yet */
 {0xE0000000,__phys_to_pfn(S3C2410_CS4),128*SZ_1M,MT_DEVICE}   // add by xionggang
};
另一种是动态映射,即用ioremap或ioremap_nocache来实现,由于以太网中断频频发生,这里为了效率采用静态映射。
================================================================
1)、在linux-2.6.24/arch/arm/mach-s3c2410/devs.c 中添加
#include   // add by xionggang
并添加
/* DM9000-board resource, add by xionggang */
static struct resource eduk_dm9000_board_resource[] = {
 [0]= {
  .start = 0x20000000,  // this is based on edukit-iv board
  .end   = 0x20000003,
  .flags  = IORESOURCE_MEM,
 },
 [1]={
  .start = 0x20100000,
  .end   = 0x20100003,
  .flags = IORESOURCE_MEM,
 },
 [2]={
  .start = IRQ_EINT9,
  .end   = IRQ_EINT9,
  .flags = IORESOURCE_IRQ,
 }
};

static struct dm9000_plat_data eduk_dm9000_board_platdata ={
 .flags = DM9000_PLATF_16BITONLY,//work in 16bit mode
};

struct platform_device eduk_dm9000_board_device = {
 .name = "dm9000-board",
 .id = -2,
 .num_resources = 3,
 .resource = eduk_dm9000_board_resource,
 .dev = {
 .platform_data = &eduk_dm9000_board_platdata,
 }
};
EXPORT_SYMBOL(eduk_dm9000_board_device);
2)、在linux-2.6.24/include/asm-arm/plat-s3c24xx/devs.h 中声明平台设备 eduk_dm9000_board_device ,在适当位置添加以下内容:
extern struct platform_device eduk_dm9000_board_device;  // add by xionggang
3)、在linux-2.6.24/arch/arm/mach-s3c2410/mach-smdk2410.c中将eduk_dm9000_board_device添加到平台设备列表中:
static struct platform_device *smdk2410_devices[] __initdata = {
 &s3c_device_usb,
 &s3c_device_lcd,
 &s3c_device_wdt,
 &s3c_device_i2c,
 &s3c_device_iis,
 &eduk_dm9000_device, // add by xionggang
 &eduk_dm9000_board_device, // add by xionggang
};

static struct map_desc smdk2410_iodesc[] __initdata = {
  /* nothing here yet */
};
中添加以下内容:
static struct map_desc smdk2410_iodesc[] __initdata = {
  /* nothing here yet */
 {0xE0000000,__phys_to_pfn(S3C2410_CS4),128*SZ_1M,MT_DEVICE}   // add by xionggang
};
下面主要是设置MAC地址和中断
GPGCON(56000060)GPG1[3:2]置10,功能设置为EINT9。这可以用函数实现:s3c2410_gpio_cfgpin(S3C2410_GPG1, S3C2410_GPG1_EINT9);  
EXTINT1(5600008c)[6:4]置10 边沿触发中断,一定要设置边沿触发,否则会一直产生中断。
EINTMASK(560000a4)[9]置0以enable interrupt EINT9
INTMASK (4A000008)[5] 置0 使能EINT8_23。
将CPLD控制寄存器(0x22600000)的bit7置0,开中断,注意在置0之前先置1(未知原因)。
4)、将linux-2.6.24/drivers/net/dm9000.c复制到当前文件夹中,并改名为dm9000-board.c,在dm9000-board.c中添加头文件,已有则略过:
#include   // add by xionggang
在代码部分上面添加或修改为:
/* add by xionggang ,dm9000 interrupt */
static char net_mac_addr[]={0x01,0xe0,0x3d,0xf4,0xdd,0xf7}; // MAC
static void *eintmask,*extint1, *intmsk,*cpldcontrol; 
#define EINTMASK     (0x560000a4) // 外部中断
#define EXTINT1          (0x5600008c) // 外部中断方式
#define INTMSK           (0x4A000008) // 中断屏蔽
#define CPLDControl      (0x22600000) // CPLD控制寄存器
5)、在当前文件中的
 /* Set Node Address */
 for (i = 0; i < 6; i++)
  ndev->dev_addr[i] = db->srom[i];
的后面
 if (!is_valid_ether_addr(ndev->dev_addr)) {
  /* try reading from mac */

  for (i = 0; i < 6; i++)
   ndev->dev_addr[i] = ior(db, i+DM9000_PAR);
 }
的前面
加上以下内容:
/*********** add by xionggang ********/
 for(i=0;i<6;i++){
  ndev->dev_addr[i]=net_mac_addr[i];
 }
 eintmask=ioremap_nocache(EINTMASK,4);
 extint1=ioremap_nocache(EXTINT1,4);
 intmsk=ioremap_nocache(INTMSK,4);
 cpldcontrol=ioremap_nocache(CPLDControl,4);

 s3c2410_gpio_cfgpin(S3C2410_GPG1, S3C2410_GPG1_EINT9);

 writel(readl(eintmask) & (~(1<<9)),eintmask);
 writel(readl(extint1) & (~(7<<4)),extint1);
 writel(readl(extint1) | (2<<4),extint1);  // 下降沿触发,CPLD共用的中断EINT9最好是边沿触发
 writel(readl(intmsk) & (~(1<<5)),intmsk);

 writeb(0xFF,cpldcontrol);   // 先写1
 writeb(0x7F,cpldcontrol);   // 再写0,只开net中断

 iounmap(eintmask);
 iounmap(extint1);
 iounmap(intmsk);
 iounmap(cpldcontrol);
/******************end **************/
6)、修改当前文件的以下部分
static struct platform_driver dm9000_driver = {
 .driver = {
  .name    = "dm9000",
  .owner  = THIS_MODULE,
 },
 .probe   = dm9000_probe,
 .remove  = dm9000_drv_remove,
 .suspend = dm9000_drv_suspend,
 .resume  = dm9000_drv_resume,
};

static struct platform_driver dm9000_driver = {
 .driver = {
  .name    = "dm9000-board",
  .owner  = THIS_MODULE,
 },
 .probe   = dm9000_probe,
 .remove  = dm9000_drv_remove,
 .suspend = dm9000_drv_suspend,
 .resume  = dm9000_drv_resume,
};
保持platform_device名称和platform_driver一致。
7)、修改中断服务程序,在
 struct net_device *dev = dev_id;
 board_info_t *db;
 int int_status;
 u8 reg_save;
后加上
 static unsigned char cpldstatus;

 // cpld 状态寄存器物理地址: 0x22200000。0x20000000已静态映射到0xE0000000
 cpldstatus = inb(0xE0000000 + 0x02200000);
 if((cpldstatus & 0x80) != 0)
 {
  // 非net中断,打印相关信息
  printk("CPLD interrupt occured,cpld status register value: 0x%2x\n",cpldstatus);
  return IRQ_HANDLED;
 }
8)、将
#define CARDNAME "dm9000"
改为
#define CARDNAME "dm9000-board"    // by xionggang
应该也可不改。
9)、在/driver/net/Kconfig的
config DM9000
 tristate "DM9000 support"
 depends on ARM || BLACKFIN || MIPS
 select CRC32
 select MII
 ---help---
   Support for DM9000 chipset.

   To compile this driver as a module, choose M here.  The module
   will be called dm9000.
后面加上
config DM9000_BOARD
 tristate "DM9000_BOARD support"
 depends on ARM || BLACKFIN || MIPS
 select CRC32
 select MII
 ---help---
   Support for DM9000 on the edukit4 board.

   To compile this driver as a module, choose M here.  The module
   will be called dm9000-board.
使得make menuconfig后出现DM9000_BOARD项
10)、在/driver/net/Makefile的
obj-$(CONFIG_DM9000) += dm9000.o
后加上
obj-$(CONFIG_DM9000_BOARD) += dm9000-board.o

重新配置内核,并将DM9000_BOARD编译进内核。

到此以太网移植源码部分修改完毕,在配置内核时需要选中DM9000驱动,重新编译之后,就可通过以下启动参数来挂载nfs文件系统了:
root=/dev/nfs rw nfsroot="192".168.2.80:/xgnfs ip="192".168.2.199:192.168.2.80:192.168.2.1:255.255.255.0:edukit-iv:eth1:off console="ttySAC1",115200 init="/linuxrc" noinitrd
致此,核心板DM9000A主板驱动移植结束,运行效果很好,不出现有些像严重丢包,不能下大文件,不能通过交换机的情况。通过交换机一样工作很好,没有丢包现象。
而且可以同时使用核心板和主板上的网口,经过测试将网段设成不同段,eth0 192.168.1.199,eth1 192.168.2.199。分别ping 192.168.1.80和ping 192.168.2.80,效果
非常好,无任何问题。

注:在移植2.6.14主板上网卡驱动时,死活通不了,后面抓包分析,发现dm9000想发送一个字节数据,结果却发出去两个字节,而且总是两个字 节中高字节是随机的。低字节才是想发出去的字节。比如以太网帧的头部可能为FF FF FF FF FF FF,发出去的则可能为FF 00 FF 00 FF 00 FF 00 FF 00 FF 00。这样对方显然得不到正确的包,是错误的,往往不回应。经过分析,可能是总线位宽的问题,需要将2410 bswcon寄存的[16:17]置01,配置bank4数据总线宽度为16位,因为dm9000工作在16位模式(由硬件连接决定)。而且配置程序最好 在dm9000的open函数中,不要放在probe中。否则在probe函数后又会将[16:17]改为00,8位。这样dm9000会出现上面说的问 题。

为什么在2.6.24中不需要设置,因为默认情况下,已经是16位,而且2.6.24中的dm9000驱动没有将[16:17]修改为00。因此不需要在open中重新将[16:17]设置为01。
================================================================
第6阶段 LCD驱动
================================================================
EduKit IV型箱上使用的是linux 2.6.14内核,LCD驱动已做好,现在需要在2.6.24版本上将LCD驱动加进来。原2.6.14中关于LCD的配置源程序如下:
linux-2.6.14/arch/arm/mach-s3c2410/mach-smdk2410.c
static struct s3c2410fb_mach_info smdk2410_lcd_platdata = {
 .width= 640,
 .height= 480,
 .xres = {
  .defval= 640,
  .min= 640,
  .max= 640,
 },
 .yres = {
  .defval= 480,
  .min= 480,
  .max= 480,
 },
 .bpp = {
  .defval= 16,
  .min= 16,
  .max= 16,
 },
 .regs = {
  .lcdcon1= S3C2410_LCDCON1_TFT16BPP | S3C2410_LCDCON1_TFT | S3C2410_LCDCON1_CLKVAL(1),
  .lcdcon2= S3C2410_LCDCON2_LINEVAL(479) | S3C2410_LCDCON2_VBPD(32) | S3C2410_LCDCON2_VFPD(9) | S3C2410_LCDCON2_VSPW(1),
  .lcdcon3= S3C2410_LCDCON3_HOZVAL(639) | S3C2410_LCDCON3_HBPD(47) | S3C2410_LCDCON3_HFPD(15),
  .lcdcon4= S3C2410_LCDCON4_HSPW(95) | S3C2410_LCDCON4_MVAL(13),
  .lcdcon5= S3C2410_LCDCON5_FRM565 | S3C2410_LCDCON5_HWSWP | S3C2410_LCDCON5_PWREN | S3C2410_LCDCON5_INVVLINE | S3C2410_LCDCON5_INVVFRAME,
 },
 .gpcup= 0xFFFFFFFF,
 .gpcup_mask= 0xFFFFFFFF,
 .gpccon= 0xaaaaaaaa,
 .gpccon_mask= 0xFFFFFFFF,
 .gpdup= 0xFFFFFFFF,
 .gpdup_mask= 0xFFFFFFFF,
 .gpdcon= 0xaaaaaaaa,
 .gpdcon_mask= 0xFFFFFFFF,
 .lpcsel= 0x00,
};

static void __init smdk2410_map_io(void)
{
 s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
 s3c24xx_init_clocks(0);
 s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
 s3c24xx_set_board(&smdk2410_board);
 
 set_s3c2410fb_info(&smdk2410_lcd_platdata);
 s3c2410_init_usb();
}
而 在2.6.24内核中有了重大的数据结构变化,首先他把结构拆成了二部分,一个结构是s3c2410fb_display另一个结构是 s3c2410fb_mach_info,所以先根据这二个数据结构进行拆分上述结构。在linux-2.6.24/arch/arm/mach- s3c2410/mach-smdk2410.c中
使用如下的LCD配置源码:
/* add by xionggang */
static struct s3c2410fb_display edukit2410_lcd_cfg[] __initdata = {
 {
  // Config for 240x320 LCD
  .lcdcon5= S3C2410_LCDCON5_FRM565 | S3C2410_LCDCON5_HWSWP | S3C2410_LCDCON5_PWREN | S3C2410_LCDCON5_INVVLINE | S3C2410_LCDCON5_INVVFRAME,

  .type   = S3C2410_LCDCON1_TFT,
  .width   = 640,
  .height   = 480,
  //.pixclock  = 174757, // HCLK/10
  .xres   = 640,
  .yres   = 480,
  .bpp   = 16,
  .left_margin  = 16,
  .right_margin  = 48,
  .hsync_len  = 96,
  .upper_margin  = 33,
  .lower_margin  = 10,
  .vsync_len = 2,
 }
};

/* add by xionggang */
static struct s3c2410fb_mach_info edukit2410_fb_info __initdata = {
 .displays  = edukit2410_lcd_cfg,
 .num_displays = ARRAY_SIZE(edukit2410_lcd_cfg),
 .default_display = 0,
 .gpcup= 0xFFFFFFFF,
 .gpcup_mask= 0xFFFFFFFF,
 .gpccon= 0xaaaaaaaa,
 .gpccon_mask= 0xFFFFFFFF,
 .gpdup= 0xFFFFFFFF,
 .gpdup_mask= 0xFFFFFFFF,
 .gpdcon= 0xaaaaaaaa,
 .gpdcon_mask= 0xFFFFFFFF,
 .lpcsel= 0x00,

};
并在当前文件的static void __init smdk2410_map_io(void)函数中添加
 s3c24xx_fb_set_platdata(&edukit2410_fb_info);  // by xionggang
如下:
static void __init smdk2410_map_io(void)
{
 s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
 s3c24xx_init_clocks(0);
 s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
 s3c24xx_fb_set_platdata(&edukit2410_fb_info);  // by xionggang
}

2.6.24结构中对寄存器lcdcon1-4全部用函数进行了自动设置,我们只需对lcdcon5进行设置,但是并不说明其他的数据不重要,或者不用设置,重点在这几个数值上
引用:

    .left_margin = 16,根据下边的函数S3C2410_LCDCON3_HFPD(var->left_margin - 1)以及2.6.14 LCD结构体smdk2410_lcd_platdata中第三个寄存器的数据S3C2410_LCDCON3_HFPD(15)可确定该值。
    .right_margin = 48,同上,以此类推
    .hsync_len = 96,同上,以此类推
    .upper_margin = 33, 同上,以此类推
    .lower_margin = 10,同上,以此类推
    .vsync_len = 2,同上,以此类推

以下函数是s3c2410 LCD控制器的驱动,其所在源文件为:linux-2.6.24/drivers/video/s3c2410fb.c
/* s3c2410fb_calculate_tft_lcd_regs
 *
 * calculate register values from var settings
 */
static void s3c2410fb_calculate_tft_lcd_regs(const struct fb_info *info,
          struct s3c2410fb_hw *regs)
{
 const struct s3c2410fb_info *fbi = info->par;
 const struct fb_var_screeninfo *var = &info->var;

 switch (var->bits_per_pixel) {
 case 1:
  regs->lcdcon1 |= S3C2410_LCDCON1_TFT1BPP;
  break;
 case 2:
  regs->lcdcon1 |= S3C2410_LCDCON1_TFT2BPP;
  break;
 case 4:
  regs->lcdcon1 |= S3C2410_LCDCON1_TFT4BPP;
  break;
 case 8:
  regs->lcdcon1 |= S3C2410_LCDCON1_TFT8BPP;
  regs->lcdcon5 |= S3C2410_LCDCON5_BSWP |
     S3C2410_LCDCON5_FRM565;
  regs->lcdcon5 &= ~S3C2410_LCDCON5_HWSWP;
  break;
 case 16:
  regs->lcdcon1 |= S3C2410_LCDCON1_TFT16BPP;
  regs->lcdcon5 &= ~S3C2410_LCDCON5_BSWP;
  regs->lcdcon5 |= S3C2410_LCDCON5_HWSWP;
  break;
 case 32:
  regs->lcdcon1 |= S3C2410_LCDCON1_TFT24BPP;
  regs->lcdcon5 &= ~(S3C2410_LCDCON5_BSWP |
       S3C2410_LCDCON5_HWSWP |
       S3C2410_LCDCON5_BPP24BL);
  break;
 default:
  /* invalid pixel depth */
  dev_err(fbi->dev, "invalid bpp %d\n",
   var->bits_per_pixel);
 }
 /* update X/Y info */
 dprintk("setting vert: up=%d, low=%d, sync=%d\n",
  var->upper_margin, var->lower_margin, var->vsync_len);

 dprintk("setting horz: lft=%d, rt=%d, sync=%d\n",
  var->left_margin, var->right_margin, var->hsync_len);

 regs->lcdcon2 = S3C2410_LCDCON2_LINEVAL(var->yres - 1) |
   S3C2410_LCDCON2_VBPD(var->upper_margin - 1) |
   S3C2410_LCDCON2_VFPD(var->lower_margin - 1) |
   S3C2410_LCDCON2_VSPW(var->vsync_len - 1);

 regs->lcdcon3 = S3C2410_LCDCON3_HBPD(var->right_margin - 1) |
   S3C2410_LCDCON3_HFPD(var->left_margin - 1) |
   S3C2410_LCDCON3_HOZVAL(var->xres - 1);

 regs->lcdcon4 = S3C2410_LCDCON4_HSPW(var->hsync_len - 1);
}
通 过对源码的修改,保存,在make menuconfig时,选中Device Drivers  --->Graphics support  ---> <*> Support for frame buffer devices  --->以及[*] Bootup logo  --->中的[*]   Standard 224-color Linux logo。重新编译之后启动内核,就会发现
LCD屏上出现小企鹅了。
关于logo的更改,在目录drivers/video/logo下替换相应用ppm图片即可,要注意颜色的对应,然后删除所生成的目标代码,重新编译即可。当然也可添加自定义的选项并加到make menuconfig中。

 

阅读(915) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~