`
isiqi
  • 浏览: 16030983 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

Linux内核升级LCD驱动的更换(开发板)

阅读更多

Linux内核升级LCD驱动的更换(开发板)

关键字

内核升级 ,更换驱动 ,LCD

本文给出了将一个已有的LCD驱动添加进一个新的linux内核中的方法


一. 概述

本文搜集整理了Linux系统编译时的主要配置选项(make config)的详细说明,供Linux裁剪特别是设备驱动和模块功能增删时使用参考。需要注意的是,每个版本linux版本的config各选项意义,命名等都可能有所差异。

1、 修改内核根目录config文件

文本方式打开config文件,将LCD的几个编译开关添加进Frame buffer hardware drivers这一项目下,之后在make menuconfig中就可以看到。

#

# Frame buffer hardware drivers

#

CONFIG_FB_SIDSA=y

CONFIG_FB_TCM=y

# CONFIG_FB_SDRAM is not set

CONFIG_TFT_AT91=y

CONFIG_FB_SIDSA_DEFAULT_BPP=16

# CONFIG_FB_SIDSA_DEBUG is not set

在控制台显示驱动项目中将linux logo显示的编译开关打开,logo显示16色或其他均可。

#

# Console display driver support

#

CONFIG_LOGO=y

# CONFIG_LOGO_LINUX_MONO is not set

CONFIG_LOGO_LINUX_VGA16=y

添加好上述config选项后,使用make menuconfig打开该config文件,即可看到这些选项,一一进行确认:

LCD的配置项位于drivers->graphices support下 分别将frame buffer和logo的选项选中,才能使用逻辑屏和logo图片。Bootup logo中可选黑白图,16色图或256色图其中一种均可。

clip_image002

Frame buffer的设备驱动选中SIDSA控制器,目前逻辑屏比较小为QVGA,数据源选为TCM等选项。开发板具有内置大约1M多的SRAM,当逻辑屏比较大时,应选SDRAM.

clip_image004

2、 添加屏驱动源码到工程目录

Linux的屏驱动一般位于drivers\video 目录下,目前AT91SAM926开发板使用的LCD驱动是sidsafb.c和sidsafb.h,at91sam9261_lcdc.h三个文件,在标准的linux2.6.25上是没有的,从开发板源码包中复制过来放到该目录下(还要进行一些代码修改,后面的步骤会讲到)。

3、修改逻辑屏驱动模块的Makefile文件

打开drivers\video目录下的Makefile文件,在其中添加sidsafb.o文件的编译选项,依赖于编译开关CONFIG_FB_SIDSA,也可使用文件比较的方式和开发板同名makefile比较,将下图蓝色方框部分复制到你的makefile

clip_image006

4、修改模块的Kconfig文件

打开drivers\video目录下的Kconfig文件,添加FB_SIDSA, FB_TCM等几个编译开关的配置,也可使用文件比较器将开发板源码包下的同名Kconfig文件比较,将下图蓝色方框部分的几个编译开关选项复制添加到你的drivers\video\Kconfig中,如下图:

clip_image008

5、源代码的修改

移植驱动时有两种工作方式,一种是所有驱动同时一并移植,这样做的好处是各驱动模块公共文件如寄存器表,相关宏的头文件放置的比较合理,移植完后清晰,缺点是交叉错误多,调试工作量大,一两个人无法完成。另一种是单个模块串行一一移植,好处是调试比较好调,缺点是移植完代码可能比较乱。综合一下,个人认为驱动整合移植时先移植所有公共的头文件,公共的功能函数和宏,不添加具体模块,编译出一个基本版本,在此版本基础上在分头移植各个模块比较合理。

单驱动模块移植时,总结下来源代码的修改主要包括几个部分:

a) 驱动的依赖关系整理清楚,若本驱动还依赖其他驱动,则还需要先移植添加其他驱动模块

b) 理清所添加驱动对外部变量,函数,宏的引用关系,去除编译错误。

c) 修改虚拟地址->物理地址的映射函数为当前平台的映射函数,使寄存器map表映射正确。

d) 修改驱动的注册和加载部分。

具体改动如下:(此部分改动已有改好的版本在FTP,列举只是为了说明问题和给出方法)

模块依赖关系和编译错误的整理

由于本开发板的屏是RGB屏,所以实际驱动是由AT91所带的LCDC控制器来完成,因此屏的驱动主要工作是配置LCDC和管理Frame buffer两部分。LCDC依赖于另外两个模块:IO和CLOCK(即代码中的PIO和PMC模块),IO用来控制LCDC的电源,CLOCK用来给出LCDC时序的时基。所以先要添加PIO和PMC部分的代码.为了不至于要挂载整个PIO和PMC模块,开发板的BSP将一些简单的功能独立出来作为函数供其他模块调用。

从开发板源码中找到PIO的寄存器定义相关宏,拷贝出来添加到sidsafb.c头部或sidsafb.h,不嫌麻烦的话也可另建头文件,PIO的寄存器主要是这些宏:

#define PIO_PER (0x0000) /**< PIO Enable Register */

#define PIO_PDR (0x0004) /**< PIO Disable Register */

#define PIO_PSR (0x0008) /**< PIO Status Register */

#define PIO_OER (0x0010) /**< Output Enable Register */

#define PIO_ODR (0x0014) /**< Output Disable Registerr */

#define PIO_OSR (0x0018) /**< Output Status Register */

#define PIO_IFER (0x0020) /**< Input Filter Enable Register */

………

同样添加PMC模块的寄存器宏,主要是这些:

#define PMC_SCER (0x0000) /**< System Clock Enable Register */

#define PMC_SCDR (0x0004) /**< System Clock Disable Register */

#define PMC_SCSR (0x0008) /**< System Clock Status Register */

#define PMC_PCER (0x0010) /**< Peripheral Clock Enable Register */

#define PMC_PCDR (0x0014) /**< Peripheral Clock Disable Register */

#define PMC_PCSR (0x0018) /**< Peripheral Clock Status Register */

#define PMC_MOR (0x0020) /**< Main Oscillator Register */

……..

添加各模块寄存器读写的宏

#define readreg_pmc(offset) readl(AT91C_VA_BASE_PMC + offset)

#define writereg_pmc(value, offset) writel(value, (AT91C_VA_BASE_PMC + offset))

有了这些宏,对IO和CLOCK的操作函数基本就可以加进来编译,屏驱动中引用到的操作函数主要是:

at91_gpio_set_level

at91_gpio_periph_enable

at91_gpio_configure

at91_device_pio_setup

at91_enable_periph_clock

at91_disable_system_clock

at91_enable_system_clock

at91_lcdc_clock_enable

at91_lcdc_power_up

虚拟地址-物理地址转换函数的修改

去除上述产生的所有编译错误,将其他一些零碎的未定义的对象添加进来,基本就可以编译通过了。但还不能运行,一般地讲,两个linux版本的虚拟地址到物理地址的转换关系是不一致的,而驱动对寄存器的访问都是通过虚拟地址进行,因此要使驱动能在新的linux内核上运行,必须使用该linux的虚拟地址-物理地址转换公式,获取到正确的寄存器虚拟地址。

Linux系统的设备内存映射都映射到系统空间(0xc00000000-0xFFFFFFFF)的固定映射区之内,映射方式是线性、连续的,因此设备的物理地址和虚拟地址只相差一个常数偏移量,当物理内存小于896M时,高端映射区未用,固定映射区的首地址一般就是紧接在vmalloc区的后面,不同的版本不同的芯片体系中vmalloc区的尾地址定义有所不同,在vmalloc.h中定义:

Linux 2.6.15-AT91定义为

#define VMALLOC_END (0xFF000000 - 0x00200000)

Linux 2.6.25-AT91定义为

#define VMALLOC_END (AT91_VIRT_BASE & PGDIR_MASK)

在Linux2.6.15-AT91体系中,物理地址到虚拟地址的转换相差的常数依赖于VMALLOC_END(/include/asm-arm/arch-at91sam9261/hardware.h):

#define AT91C_IO_PHYS_BASE 0xFFFFF000

#define AT91C_IO_VIRT_BASE VMALLOC_END

/* Convert a physical IO address to virtual IO address */

#define AT91_IO_P2V(x) ((x) - AT91C_IO_PHYS_BASE + AT91C_IO_VIRT_BASE)

即物理地址转换为虚拟地址时,虚拟地址=物理地址-(0xFFFFF000- VMALLOC_END)

在Linux2.6.25-AT91体系中,IO物理地址到物理地址转换公式为:

#define AT91_IO_P2V(x) ((x) - AT91_IO_PHYS_BASE + AT91_IO_VIRT_BASE)

但其物理基地址AT91_IO_PHYS_BASE和虚拟基地址AT91_IO_VIRT_BASE和Linux2.6.15版本均不同,(由于对其的长度不同,因此IO物理基地址可能不同版本都不同,但具体到任意一个寄存器的物理地址,最终换算出来基地址+OFFSET都是一样的),因此寄存器的访问,必须采用当前体系的基地址,当前体系的OFFSET,当前体系的映射方式AT91_IO_P2V,才能得到当前体系下对应的正确的虚拟地址。

代码中将旧的映射函数AT91_IO_P2V屏蔽不用,采用新版本同名的AT91_IO_P2V映射函数,并将所有使用到的寄存器基地址,偏移量修改为当前体系的值,此处只用到LCDC,PIO,PMC三片寄存器,将其基地址改为当前版本定义值:

#define AT91C_VA_BASE_PIOA AT91_IO_P2V(AT91C_BASE_PIOA)

#define AT91C_VA_BASE_PMC AT91_IO_P2V(AT91C_BASE_PMC)

改为

#define AT91C_VA_BASE_PIOA AT91_IO_P2V(AT91_PIOA)

#define AT91C_VA_BASE_PMC AT91_IO_P2V(AT91_PMC)

至此,在当前体系下寄存器的虚拟地址就可以正确地得到了,使用虚拟地址去配置寄存器,才不会产生分页错,data abort之类地内存错误,
设备注册和初始化的修改

设备的注册和初始化一般位于arch\arm\对应体系目录下,使用AT91芯片时,主要是at91sam9261.c,at91sam9261_devices.c和board-sam9261ek.c三个代码文件和一些.h文件,第一个at91sam9261.c负责总的调用和定义,第二个at91sam9261_devices.c负责主要片内控制器的定义,初始化,其中LCDC就包含在这里面。第三个board-sam9261ek.c负责片外板上设备的定义和初始化,同一款芯片不同的板子不同的硬件在这里区别。

在at91sam9261_devices.c中找到LCD的定义和初始化,标准Linux2.6.25使用的是CONFIG_FB_ATMEL,将其改为当前开发板对应的代码,主要是RGB屏时序的定义,FB的位置区域,和普通设备device不一样,LCDC属于平台标配设备,其类型为platform_device,需要定义对DMA的使用等,将其设备名改为sidsafb.c文件中定义的"sidsa-lcdc",这样启动时才能找到"sidsa-lcdc"并将其挂载。这样,LCD驱动就移植完毕,编译通过,烧写后启动即可亮屏,如果想修改logo图片,到drivers\video\logo目录下修改图片,或直接修改其对应的数组。

LCDC的设备是:

static struct platform_device at91_lcdc_device = {

.name = "sidsa-lcdc",

.id = 0,

.num_resources = ARRAY_SIZE(lcdc_resources),

.resource = lcdc_resources,

.dev = {

.dma_mask = &lcdc_dmamask,

.coherent_dma_mask = DMA_BIT_MASK(32),

.platform_data = &lcdc_data,

},

};

调试过程中可在关键的函数中使用printk添加一些打印语句,如:

init/main.c中的start_kernel函数是内核启动的第一个函数,在这里进行各项初始化,可在其中加一些打印观察情况;

at91sam9260.c和at91sam9261_devices.c中进行芯片设备的加载,可加一些打印,观察哪些设备加载成功,哪些加载失败。

观察所加的设备"sidsa-lcdc”是否被正常挂载,可在设备的初始化函数sidsafb_init中添加打印,观察是否进入其中初始化,且注册设备driver_register时返回的值是否正确等。

编译时,要使用AT91-SAM926的config文件,由于每个板子的内存基地址和长度不一样,因此要在config中定义,也可以在代码中定义:(include\asm-arm\arch-at91\hardware.h)

#define AT91_SDRAM_BASE 0x20000000

屏基本上可以亮了,但还有个bug,就是显示完logo后之后一会儿就灭掉了,这是因为Linux2.6.25版本上的默认BSP时钟使用情况和现有开发板不一致,LCD定义的CLOCK有冲突,将如下CLK定义宏暂时注销即可正常显示:

//#define AT91_PMC_HCK1(1 << 17) /* AHB Clock (LCD) [AT91SAM9261 only] */

//lingzj remove

#define AT91_PMC_HCK1 (1 << 1) /* AHB Clock (LCD) [AT91SAM9261 only] */

—— 完 ——

分享到:
评论

相关推荐

    基于linux2.6.30.4 framebuffer移植LCD驱动到FL2440开发板

    3、 内核LCD驱动机制framebuffer(帧缓冲技术)概述; 4、 驱动移植相关及应用程序接口相关重要数据结构分析 5、 在linux2.6.30.4内核中添加(移植)LCD驱动; 6、 嵌入式linux应用程序中LCD驱动接口函数的调用及其...

    linux 内核: linux-2.6.32.24-20240320-work.gz, 支出mini2440 开发板

    1. linux 内核: linux-2.6.32.24_20240320_work.gz, 支出mini2440 开发板 2. LCD 屏幕为: P43 3. 支持板卡上的全部驱动

    Linux设备驱动程序开发详解

    《Linux设备驱动开发详解》是一本介绍Linux设备驱动开发理论、框架与实例的书,《Linux设备驱动开发详解(第2版)》基于LDD6410开发板,以Linux2.6 版本内核为蓝本,详细介绍自旋锁、信号量、完成量、中断顶/底半部、...

    天祥电子-linux2.6.31移植V1.5-完整版

    四、LCD驱动的移植 五、DM9000 驱动的移植 六、UDA1341 声卡驱动的移植 七、SD 卡驱动移植 八、RTC 驱动移植 九、触摸屏驱动移植 十、USB 设备驱动移植 十一、USB 摄像头驱动移植 十二、CMOS 摄像头驱动移植 十三、...

    史上最强的嵌入式底层驱动开发课程 Linux系统开发+Linux高级程序+主板开发+ARM等

    │ ├66 - 驱动开发板资源7.mp4 │ ├67 - bootloader概述1.mp4 │ ├68 - bootloader概述2 .avi │ ├69 - bootloader概述3.avi │ ├70 - bootloader概述4.mp4 │ ├71 - bootloader概述5.mp4 │ ├72 - C5工程...

    Linux设备驱动开发

    这是一本介绍Linux设备驱动开发理论、框架与实例的书,《Linux设备驱动开发详解(第2版)》基于LDD6410开发板,以Linux2.6 版本内核为蓝本,详细介绍自旋锁、信号量、完成量、中断顶/底半部、定时器、内存和I/O映射...

    linux-2.6.29.1在utu2440上的移植(含lcd驱动移植)

    linux-2.6.29.1在utu2440开发板上的移植(含LCD驱动移植)

    Linux设备驱动

    《Linux设备驱动开发详解(第2版)》是一本介绍Linux设备驱动开发理论、框架与实例的书,《Linux设备驱动开发详解(第2版)》基于LDD6410开发板,以Linux2.6 版本内核为蓝本,详细介绍自旋锁、信号量、完成量、中断顶/底...

    嵌入式Linux应用开发完全手册.pdf

    比如UART、I*IC、LCD等),UBoot、Linux内核的分析、配置和移植,根文件系统的构造(包括移植busybox、glibc、制作映象文件等),内核调试技术(比如添加kgdb补丁、栈回溯等),驱动程序编写及移植(LED、按键、扩展串口、...

    天祥ARM开发板 TX-3C开发板使用手册

    2.linux2.4内核驱动程序 (1)LED (2)Linux中断 (3)UART全串行口控制台 (4)RTC(实时时钟) (5)片内A/D采集LM35 (6)PS2键盘和鼠标 (7)RTL8019A (8)IDE硬盘 (9)USB主功能 (10)USB从功能 3.Linux...

    嵌入式Linux应用开发完全手册 清晰版PDF 有书签

    LCD 等),U-Boot、Linux 内核的分析、配置和移植,根文件系统的构造(包括移植 busybox、glibc、制作 映象文件等),内核调试技术(比如添加 kgdb 补丁、栈回溯等),驱动程序编写及移植(LED、按键、扩展 串口、...

    Linux下播放器开发-交叉编译Mplayer.pdf

    开发板采用友善之臂的Tiny4412开发板,MCU是三星的EXYNOS4412,板子上接的LCD分辨率为800*480,帧缓冲驱动框架接口,Linux内核版本是3.5,系统不带图形界面,文件系统是采用busybox制作的最小根文件系统,整个系统...

    Linux小项目-数码相册设计.pdf

    这是基于Linux系统开发板设计一个小项目-数码相册,在LCD屏上可以显示完成常见的图片显示,翻页、旋转、缩放等功能。 开发板采用友善之臂的Tiny4412开发板,CPU是三星的4412,最高主频1.5GHZ。板子配有8G的EMMC,2G...

    使用Qt开发的linux嵌入式设备监控、管理框架.rar

    采用Linux内核的V4L2视频驱动架构来驱动摄像头获取图像数据,支持MJPEG、JPEG、YUV等格式图像,采用socket与web端通信,将一帧帧的图像发送给Web端,这就实现了捕获摄像头图像的功能。若开发板是带LCD屏的还可添加...

    AT91SAM9263开发板SBC6300X.rar

    预装Microsoft WinCE 6.0或Linux 2.6操作系统,提供相关驱动源码 l 提供全部板载外设驱动程序说明及相关测试程序 UploadFile/2009/09/DownloadFile/SBC6300X_1.rar 再来个底板特性 底板特性: 类别 功能 参数 存储...

    嵌入式Linux应用开发完全手册

    比如UART、I*IC、LCD等),UBoot、Linux内核的分析、配置和移植,根文件系统的构造(包括移植busybox、glibc、制作映象文件等),内核调试技术(比如添加kgdb补丁、栈回溯等),驱动程序编写及移植(LED、按键、扩展串口、...

    ARM9嵌入式Linux开发 ppt——周卫老师

     分析Linux内核的代码结构以及启动过程,并介绍如何移植到开发板上。  介绍嵌入式Linux文件系统的目录结构,然后构造嵌入式Linux文件系统。  嵌入式Linux驱动程序开发和移植。 嵌入式系统中的GUI介绍。  ...

    嵌入式Linux小项目_倒车影像

    这是嵌入式Linux小项目_倒车影像源码。...摄像头采用USB免驱是摄像头,所有不需要编写驱动,LCD屏是友善之臂自己的7寸电容触摸屏,驱动是官方内核自带的,也不需要编写;剩下的超声波模块,蜂鸣器,需要自己填写驱动。

    郭天祥ARM9视频教程(第13和20讲均可观看).docx

    3. LCD驱动,音频驱动简介 4. 网络设备驱动分析 第九部分 QT图形界面开发 第二十一讲 QT及Qtopia介绍 1. 嵌入式GUI简介 2. Qt概述,Qt/X11的安装(Qt-4.5.3) 3. Qtopia概述 第二十二讲 Qt在ARM平台的移植 1. 移植...

    嵌入式\(高校应用案例)北航软件学院

    内核驱动设计――LCD驱动移植;音频驱动及实应用实验;USB接口试验 ZKQ090203 FPGA2/SOPC 基于NIOSII嵌入式软处理器的SOPC(可编程片上系统)系统的开发基础和设计技巧以及FPGA最小系统设计方法;SOPC实验。 ZKQ...

Global site tag (gtag.js) - Google Analytics