分类: 嵌入式
2012-05-29 13:30:33
将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
并添加
/* 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 ,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
并添加
/* 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 ,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中。