FrameBuffer驱动设计文档

来源:互联网 发布:淘宝开店经营地址无效 编辑:程序博客网 时间:2024/05/16 08:06
FrameBuffer驱动设计文档
内核版本: linux-2.4.21
文档设计: 侯辉华
版 本: 1.01
时 间: 2007/03/10
文档简介:
本文描述了如何完成framebuffer驱动的过程,并详细介绍了整个完成过程中所遇到的的一些基础问题及相应解决办法,内容安排顺序依据整个工作的进展来.
[1]. 开始应该注意linux的基础.
当时初步分析LINUX时, 没有安装LINUX系统,以立宇泰的LINUX开发包为基础,怎么搞也没能在CYGWIN下编译成功, 当时对于LINUX的配制以及编译过程都没有任何了解, 遇到错误提示不知原因, 在MAKE DEP出现错误,亦不知原因是什么…
要知道,LINUX的配制如果不正确,make dep以及后面的make zImage的问题那是千奇百怪的,不一而足,不同环境根本说不清楚.所以要能自己独立的解决问题,还必须对于配置以及make dep等等过程有一个大至的理解才行,这样有问题才可能进行分析.
[2]. 文档主要内容.
以下简单的记录一下近段时间在LINUX上基础方面一些介绍. 其实仅对初学者有帮助,因为初学者根本很多基本的东西都不知道,但是这些不知道的东西在网上基本没有全面的介绍,仅仅可以在不同的文章当中,可能会只言片语的顺便带出,因此在这里我仅以自己初学的过程做一记录, 希望大家可以分享我的苦与乐, 不要象我一样再痛苦一次...
有点后悔没有当天记录, 以至于丢失了最原始的茫然与无助的感觉...追忆莫及...
我虽然有了几年的编程和学习经验, 也看过不少的嵌入式的系统软件, 代码规模也不小,对GUI方面也有很多深入的学习与了解, 但是对于LINUX,水平是比较次的, 以前工作的时候虽然着力分析过GDB的源码, 但是感觉也是太庞大的, 不过还好能把握主体的结构, 也基本完成了移值,之后就放下了, 对于LINUX也就是这种层次.
近时时间由于要弄一个显卡的FRAMEBUFFER驱动, 所以又不得不从零开始分析LINUX的相关东西, 遇到的问题很多, 所以希望记录下来, 可以用帮助初学者.
我的平台用的是linux-2.4.21的代码, 板子是ep9302, 不带LCD驱动, 开发包是广州公司板子提供的, 基本上同cirruslogic公司提供的无异, 周边的相关驱动都已经完成了, 但是因为要外括一个显卡上去, 所以要做的工作就是在这个开发包的基础上增加显卡的framebuffer驱动, 这个开发包在网上有下载, 他准备的很齐全, 基本上所有的包都有了, 而且建立了一个很方便的编译环境, 将很多东西捆在一起. 通过简单几个命令就可以完成工作:
如:
make linuxconfig
make linux
make ramdisk.gz
以上三个命令就完成LINUX配置,编译内核zImage, 生成虚拟盘ramdisk.gz, 如此非常方便….
如何开始接触Linux, 要大体了解些什么
分析了LINUX在ARM这方面的代码, 要看这部分还必须先搞清一些ARM的平台知识以及汇编知识.
熟悉了MAKEFILE文件规则.
熟悉LD链接器的LDS链接文件规则.
LINUX的启动加载部分, 可以支持由其它的BOOTLOADER来加载, 也可以自己加载, 这当中涉及到比较让人不太清楚的地方就是:
要理清运行时的顺序, 内核是压缩过的, 起先压缩过的的内核运行, 解压出完整的内核, 然后转去解压后的完整内核运行.
要理清楚压缩过的内核的组成部分, 分别由head.S这个启动部分, misc.c解压部分, LINUX内核压缩文件piggy.o文件.这几部分链接在一起组合输出名为linux的内核.这个链接的组成是在arch/arm/boot/compressed/vmlinux.lds.in当中指定的.piggy.o这个内核压缩文件是由arch/arm/boot/compressed/Makefile这个makefile当中产生的.产生他依赖完整的带所有符号信息的LINUX内核的ELF格式的文件, 这个文件是在linux-2.4.x/Makefile控制下生成的,由此逐层调用各个其它模块内的Makefile, 模块的划分基本依据文件夹层次结构.
要理清各个部分在内存中的位置关系, 一是压缩过的内核在什么地方, 二是解压后的内核在什么地方, 三是解压后的内核是否须要重定位而搬到其它地方.
要特别注意有些LDS链接文件是链接后生成的, 看时间就可以知道, 它的作用就是告诉你内核链接后的位置, 因为先前的LDS文件中是一些符号.
搞清楚解压后的内核包含哪些部分, 先前我们谈到压缩过的内核的组成部分, 说到包含了压缩过后的piggy.o,这个才是真正的纯内核,不包含arch/arm/boot/compressed/head.s,arch/arm/boot/compressed/misc.c这些解压缩代码,
arch/arm/kernel/head-armv.S的代码才是解压缩后的真正起始.
以上所有所讲的, 内核的组成部分必须从makefile中分析, 然后再分析各个目录下的lds连接文件, 理清了这两部分才能正确理解以上所说的几条. 才能搞清楚整个内核的配置, 包括处理器类型, 硬件板子类型等.
4月17日
有关LINUX发行版的安装
在linux面前,我是非常浅薄的,而且我以至于我开要装什么样的发行版,有什么最新发行版可装,都是不太清楚的,只是简单的停留在学校阶段时的Red Hat7.0/Tubro Linux/Blue Point/Red Flag等这些, 对于如今的Flodra/Deabin等等,都不知道的,所以还只能借助网络来查找, 所幸有找到一个好网站,人气也很旺,也积累了好多的的资料,耐心查看就是了.
www.linuxsir.org
----LINUX各种方面资料网站,虽然编程方面的显得少了,但是各种发行版安装使用方面的问题,以及文档介绍等等,都是非常好的,简单的说:1.如果遇到GRUB出问题了,如在LINUX上又装了XP,找不回LINUX启动菜单了,你可以找它;2.如果遇到不知道如何安装TFTP服务,不知道如何配置或者关闭防火墙什么的,你可以找它;3.如果想知道各种发行版的介绍以及安装相关知识,你可以找它.
一.查找LINUX的发行版,安装LINUX.
经过一番的查找, 终于了解了Fodara5是一个比较好的稳定版本(这个稳定害死我了,后面讲), 但是不知道安装源在哪里, 也不知道哪里比较快, 所以还是先去下载了Red Hat9.0这个非常这老的东西,应该是2003年的时候的吧, Fodara系统是RED HAT面对开源社区的版本, 后面REDHAT发行了企业版是收费的, RED HAT9.0因为先前就已经找到过一个下载源, 所以花了一点时间, 就找到了下载网址, 这是一个FTP.
Red Hat 9.0下载FTP:
http://www.icewalkers.com/Linux/Software/53470/Red-Hat-Linux.html
ftp://archive.download.redhat.com/pub/redhat/linux/9/
好不容易把RED HAT三张盘下载下来了, 加起来也有2G多吧,开着机品,用FlashFXP开着机器下,好在是晚上睡觉的时候,第二天一大早起来可以看到下载完成,大喜哦.不过这个FlashFXP不太好,速度不行而且经常在下载过程中弹出是不是要覆盖原来已有的文件,这是在下载半路中弹出来的,很郁闷.最好大家可以用自己的更好的FTP工具.
可是后面一想,RED HAT比较老了,我的机器很新,估计到时候安装可以硬件驱动是个麻烦事,不如找个新的发行版,这样安装之后可能会省心很多, 事实证明确是如此,后面就知道了.
最新的Fodara 5有五张安装碟,一张修复碟;如果是DVD就只有一张碟,总体的大小是4G左右.我是在官方安装源下载的,使用的是BT下载,用FLASHGET1.8正好支持,免了到处找BT下载工具,这很烦.感谢FLASHGET这个这么好的工具,一直以来都在发展,感谢.
Fodara 5下载源:
http://torrent.fedoraproject.org/
Fedora Core 5 Final - Bordeaux
bordeaux-binary-i386.torrent Fedora Core 5 Final - Bordeaux binary CD iso images for i386. 3.1GB 2006-03-20
开着机器DOWN整晚,多半都没有问题,可以下载过错成,呵呵,不要心疼爱机.
Debian 4.0发行版的安装源:
下载了Debian 4.0发行版的DVD碟,总共是3张, 大小有14G左右, 如果是CD的话据说是21张, 我是DOWN了整天才DOWN下来的,但是郁闷的是,DOWN下来我记录到DVD时, 因为是用另外一台机子下载的, 所以直接用网络记录, 因为选的刻速过高, 是16X,所以居然在第二张时刻坏了一张盘, 郁闷,最后都用6X的最低速记录, 才算平安无事.
Debain 4.0 发行版的BT下载种子:
我用的官网的, 一来稳定, 二来也好找, 三来速度也不错, 平均都有50K左右吧,种子如下:
http://cdimage.debian.org/debian-cd/4.0_r0/i386/bt-dvd/
debian-40r0-i386-DVD-1.iso.torrent 07-Apr-2007 15:03 88K
debian-40r0-i386-DVD-2.iso.torrent 07-Apr-2007 15:06 87K
debian-40r0-i386-DVD-3.iso.torrent 07-Apr-2007 15:11 85K
4月27日
WINXP与LINUX FC5双系统的共存
想着LINUX总是不太便,最惨是不能用IS来阅读代码,所以很郁闷,于是想再装一个WINXP,于是悲扰又着来了:
现在WINXP总算可以正常的使用了, 不会再上不了网,也没有中什么毒,心想可以安静一段时日了, 但是想起LINUX FC5, 还得把它找回来呀,不然就白装了,于是到:
www.linuxsir.org
一番查找,终于找到,可是执行过后,WINXP的菜单项一选择就进了LINUX去了,当时郁闷了好半天,还以为是自己的一个误操作才导致如此:
root (hd0, 5) //执行这个前我执行了一次root (hd0, 0), 开珆以为这里错,事后表面与此无关.
setup (hd0, 0)
至于正确的解决办法,那是好多天后才偶然尝试成功的,就这么一个小问题,也把我搞死,仅须改setp (hd0, 0)为setup (hd0), 就可以正常在GRUB上启动WINXP了…
2. 正式开始使用linux FC5, 遇到不少好资料.
这些资料当中,特别值得介绍一下的就是那本介绍如何自己编译一个最小型的LINUX操作系统环境的书, 而不用从发行版安装,它一步一步教我们如保建立编译工具链,以及如何建立内核,如何建立启动环境与脚本,让我们可以明白LINUX整个系统的组成,简称LFS:
Linux From Scratch
版本 6.1.1
http://man.chinaunix.net/linux/lfs/LFS-6.1.1/index.html
以上讲解了最基本的一个LINUX环境的建立过程, 后绪的别一本书接着介绍了如何建立整个GUI图形界面以有一些更加多的网络服务等:
Beyond Linux From Scratch
版本 1.0
http://docs.huihoo.com/gnu_linux/lfs/blfs-1.0/index.html
这个资料是我遇到的非常好的资料,大家可以好好的享受,多看几遍,经常的看,肯定会有很大的收获的.
3. 再有一个好的资料就是chinaunix了,这里面包含了一个linux howt中文资料,虽然网上到处都有,但是这里的比较全,便于查看:
HOWTO 索引
Linux HOWTOs
目前已经有下列的 Linux HOWTOs 存在,共计 156 篇:
http://man.chinaunix.net/linux/how/HOWTO-INDEX-3.html
4月28日
编译MINIGUI的问题
装好LINUX后, 尝试着编译了一下在PC上跑MINIGUI,配置编译倒是一路无事:
./configure
make
make install
经过这3个步骤, 编译好了MINIGUI在PC的动态库,还有如下几个小细节:
1. 编辑/etc/ld.so.conf文件, 加入一行如下内容:
/usr/local/lib
这样就指定了链接时查找MINIGUI的库路径.
2. 执行/sbin/ldconfig更新共享函数库系统的缓冲.
3. 修改GRUB的启动文件grub.conf,在kernel那一行当中,加入VGA=0x317, 以此打开FRAMEBUFFER支持.
4. 编译示例
最后兴冲冲的去MAKE示例, 结果遇到错误, 说在链接的时候找不到pthread_kill_other_threads_np()这个函数的定义,于是在IS中查找了一下,发现这个函数仅有一次调用, 就是在/src/kernel/init.c文件当中这个函数TerminateGUI():
void GUIAPI TerminateGUI (int rcByGUI)
{
if (rcByGUI >= 0) {
pthread_join (__mg_timer, NULL);
}
#ifdef __LINUX__
else {
pthread_kill_other_threads_np ();
}
#endif
于是去他的论坛www.minigui.com下面查了一下,发觉处理办法是简单的注掉就可以了, 于是注掉了,重新编译安装了一次MINIGUI, 再编译示例, 正常通过.
5. 运行示例
运行示例没有马上看到结果,提示说什么在初始化GUI时失败, 于是想起用GDB来调试,结果高度的时候,发现有些函数符号找不到,不能正常源码级跟进,百思不得其解, 于是在论坛上找找, 还是没有找到原因.
最后突然想起, 以前我在移值GDB时,用得很熟悉, 对于其执行文件格式,调试信息格式都相当熟悉, 知道在调试信息加载时如果源码文件目录不对的话, 会出现这种问题,于是直接打开MINIGUI的SO库文件来看, 发觉真的是路径有问题, 产生问题的原因是:
[1].之前我的MINIGUI是放在WINDOWS上的盘上, 挂到/mnt/e目录下, 后面把MINIGUI移到LINUX的根目录下了,是直接COPY的, 而且没有重新的配置以及清除已经编译的.o目标文件,所以那些文件的调试信息对就源码都是指向/mnt/e目录下的.
[2].因为目录指错的原因,所以GDB无法正常找到调度信息, 无法正常源码级调试,但是我不明白我的/mnt/e那个目录下的MINIGUI是存在的,为何GDB找不到,不甚明了,难道是因为mount挂上去的WIN磁盘目录有在找寻时有问题这个挂上去的分区目录在后面编译LINUX时还会提到,问题不少,到时再说.
找到不能正常调试的原因了, 于是源码级调试,最后跟到打开输入设备文件时,GDB调试器就死掉了, 不知何故, 但是差不多明白是输入设备配置的问题吧.于是在到MINIGUI上的论坛上查找,查找到原来在2.6版的内核当中,关于键盘以及MOUSE的设备名称已经变化了,不再是:
/dev/mouse
于是查找内核的dev目录, 找到MOUS设备名称:
/dev/input/mice
于是打开MINIGUI的配置文件, 注间去MINIGUI的安装目录下的ETC文件夹下找,然后修改成如上把示, 终于可以正常的运行MINIGUI的示例了...
MINIGUI还算是比较小的规模, 所以遇到问题实在很少, 以后我会详细补记我在LINUX下编译出现的种种怪问题, 以及如何解决问题的,希望大家持续关注...
4月29日
尝试建立整个开发的环境,如TFTP下载等
安装好LINUX FC5,于是准备尝试编译一下LINUX.
在编译LINUX之前,首先尝试了一下如何把开发包中本来已经编译好的映象文件DOWN到板子上运行.
1. 用烧录的东西,首先按步就斑的把redboot.bin这个文件烧录到FLASH当中,这是一个BOOTLOAD工具,而且还支持人机界面,可能通过一些命令来下载内核到RAM当中,支持TFTP服务,因为考虑到通过网络下载会快很多,于是选用TFTP.
2. 建立TFTP环境,我安装时没有选择安装TFTP服务,于是须要自己安装,在网上查找了半天,了解了TFTP服务的安装以及如何配置,如果默安装了TFTP,则根目录下面会有/tftpboot文件夹, 安装倒是比较简单:
[1]. 安装TFTP, 运行如下命令, 会直接从网终上下载安装,如果有本地光盘,可以通过Add and Remove Software来添加安装包.
yum install tftp-server
[2]. 配置TFTP,配置本来是很简单的,找到文件/etc/xinetd.d/tftp, 如果没有成功安装则不会有这个文件,如果没用安装也不会有这个文件,只须编辑一下, 把disable的由YES改成NO:
disable =no
另外还有一个特别要注意的就是防火墙的关闭,你如果开着它,就会导致下载的时候出现:
Can't load 'ramdisk.gz': operation timed out
我被这个错误提示搞得浪费了几个小时间,最后终于才在一篇文章中介绍到这个,在终端上运行:
setup
然后关掉 防火墙, 希望大家不要出现这种错误来浪费时间,这是经验教训...
[3]. 使用TFTP,如果初学的人没有用过TFTP,那么可能不太理解这个东西是如何使用的,其实相当简单,只须开启TFTP服务即可,然后把你要下传到板子上的文件放置在这个目录下即可:
开启服务: #service xinetd restart
如果你要命名板子下面可以上传文件,则要修改服务器的TFTP目录可写:
#chmod o+w /home/lqm/tftpboot
如果你已经通过Redboot把LINUX以及它的磁盘文件下载到了RAM当中,并且运行起来了,那么此时你可以在跑起来的LINUX下面运行如下命令来获取你在服务器上交*编译好的执行文件到目录板上来运行:
tftp -g -r hello 192.168.0.100
chmod + hello
./hello
3. 如何与板子进行连接, 直接在命令行运行minicom,然后进行配置,先按crtl+a, 再按 z,然后配置界面,设置串口的一些参数,这些都不会有什么问题,之后在设置完成中,选择保存设置,会将设置保存到/etc目录下,下次启动时默认加载.
在REDBOOT命令行下输入:
load -r -v -b 0x800000 -h 192.168.0.100 ramdisk.gz
load -r -v -b 0x80000 -h 912.168.0.100 zImage
exec -r 0x800000 -s 0x600000
这里,将内核ramdisk.gz下载至RAM的8M处,内核代码在512K处,ramdisk.gz大小为0x600000
这样你的板子上就会跑起LINUX来了...
总结:今天终于把整登上开发环境建立起来了,这样才可以测试自己编译的内核以及程序,不然的话没办法进行开了的.
5月12日
编译LINUX的问题
前面有讲过好多了, 但是还没有怎么讲到编译LINUX时所遇到的问题,现在正式开始进入这一块.
EP93XX开发包资源及工具文档
首先我的开发包是EP9302的, 是cirrus logic公司的, 由国内一个公司抄过来卖的, 在以下的地址可以下载到各种开发包,我的开发包中的LINUX是2.4.18版本的, 有兴趣的朋友可以到这里去下载来编译玩玩, 如果想跑起来的话,可以使用skyeye这个开源项目的虚拟机, 这个现在是支持EP系统的板子的, 最早支持的是EP7312, 现在ARM9的应该也支持了,我现在还没有拾建起这个模拟器的环境, 以后会试试, 应该会方便调试一些.
[下载EP9302系统的开发包以及工具链及相关说明帮助文档]
http://arm.cirrus.com/files/index.php
http://arm.cirrus.com/files/linux/packages/packages.tar.bz2
http://arm.cirrus.com/files/tools/arm-linux-gcc-3.3-full.tar.bz2
http://arm.cirrus.com/files/tools/arm-elf-gcc-3.2.1-full.tar.bz2
首先指出两个容易出现的错误:
1. 我先是在WINDOW下COPY光盘的开发包到磁盘E, 然后直接用WINRAR来解压, 其实用WINRAR来解压是有问题的, 一来格式不对; 二来解压时间超级长;三来解决到最后一点点的时候会报出一点错误;四来解压后发现有个别文件丢失.
2. 后面我进入LINUX后, 直接把E盘挂装到/mnt/e目录下:
mount -t 'vfat' /dev/hd8 /mnt/e
我后就开始配制, 结果配置的时候出现各种各样的错误码, 到后面编译也遇到奇怪的问题, 最后没有办法, 直接把光盘的源码包解压到LINUX的根目录下, 然后再来配置和编译, 就没有什么奇怪的问题了, 不知道这个问题是不是和挂装的目录相关, 目前还不太清楚.
现在总体说明一下LINUX配置编译的基本东西:
1. 首先要安装好针对ARM的交*编译工具链, 一般的情况下你的开发板都会为你准备好了这些东西的, 所以无须你自己去编译那么多的工具链与库, 我想这个工具是所以开发的基础,弄错了以后的工作是无法开展的.
在LINUX下就有已经打包的针对LINUX平台的工具包(.sh文件), 直接执行就可以了,不过也有那些直接解压就可以的,以下地址有打包好的arm-linux-XXX一类的工具包, 目前还不太清楚arm-elf-gcc与arm-linux-gcc到底有何区别,以后了解一下.
linux根目录为./linux-2.4.21
1. 配置LINUX:
LINUX的配置支持图形化的配置, 图形化配置时, 如果发现你的linux根目录下面有.config配置文件, 会读取这个文件作默认的配置文件.
[1]. linux的配置结果文件: ./linux-2.4.21/.config
[2].menuconfig配置支持脚本: ./linux-2.4.21/scripts, 在makedep时会编译生成一个./linux-2.4.21/scripts/mkdep的执行文件,然后调用它来产生图形配置菜单及保存配置选项,生成配置产生的头文件(autoconfi.h等).
[3]. menuconfig配置控件菜单选项: 各个模块目录下config.in, 如:
./linux-2.4.21/driver/video/config.in
./linux-2.4.21/driver/char/config.in
如果用户想要自己增加一个配置选项到LINUX当中, 则必须修改这些config.in文件, 以产生在make menuconfig时的配制菜单, 另外还要在各模块目录下的Makefile文件中增加自己相应模块的.o文件, 则其编译进内核.
注: 在后面我增加ep9302的framebuffer支持时, 就是通过修改了上面列出的两年config.in文件, 让CPU为ep9302时也显示出FB相关的支持选项, 以及键盘等支持项选.
[4].LINUX每一个相应模块下面都有一个Makefile文件, 由根目录下的Makefile文件来调用各级的Makefile文件来编译生成内核,在编译的过程当中, 还会将一个模块下的几个.O文件LD链接成一个.o文件, 提供给生成最后的内核链接使用, 如video.o, char.o,kernel.o这些分别是显卡驱动, 字符设备驱动, 内核等打包生成的, 并没有相应的video.c char.c kernel.c这些文件.
特别提醒:
请不要手动的修改配置文件, 这样修改是无用的, 因为每次makemenuconfig之后都会生成一个./linux-2.4.21/include/autoconfig.h的文件,这个文件基本上就是.config文件的C语言头文件版, 是被内核包含的一个文件, makedep时会根据这个文件来检测内核的配置并产生依赖关系,因此如果你仅仅是手动编辑这个./linux-2.4.21/.config这个配置文件是没有用的, 在makedep时肯定会说很多常量没有定义...
2007/05/15
Linux与BootLoader的传参
今天算是有些收获吧,总算把以前一些弄不清楚的问题搞明白了, 回过头来一想原来是很简单的事, 不过我觉得还是值得多说几句以记下来供初学者参考.
我的开发包是广州一家公司的, 不过他基本也照抄别人的开发包吧,什么声卡/USB/串口等, 基本上原样没什么变化吧, 就是用的EP9302, 唯一提供多的东西就是把工具链以及库等都打包了, 多少方便了些...
了解EP9302的朋友, 应该都知道这个开发包用的是LINUX 2.4.18的版本, 他自己写了一些编译的SHELL,而且它针对不同的开发板,如EP9301, EP9315等, 都在各自的一个单独文件夹中编译, 所以开发包中的LINUX源码目录还是保持整洁的,编译各种EP9302时, 是在一个叫做
EP9302文件夹下, 编译的中间代码都在一个隐藏文件.do_not_edit, 真是夹如其名,意思就是你无须修改这个文件夹了, 这只是中间编译结果存放的地方, 最后所有的生成映象都会COPY到EP9302目录下的, 外国人做事不是细心,名字取得好极了...
简单的看看EP9302下的MAKEFILE文件, 相信大多数人都没什么问题吧, 这个文件还是很方便的, 你只须要如下即可:
make linuxconfig
make linux
即完成了LINUX的配制与编译, 无须(make menuconfig, make dep, make zImage), 但如果细心的话,自己去看看开发包目录下的buildrules, 就知道具体的原因了, 为了方便他们把他封装成一些很方便的编译SHELL...
现在讲讲我所遇到的问题:
我的问题在于, 我想对EP9302增加FRAMEBUFFER的支持, 想加上显卡驱动, 但是我却总是看不到在配制菜单中有关EP9302的FRAMEBUFFER配制选项, 所以我就想借用EP9315的配制选项.
当然了, 现在我再看这个问题,在我清楚了之后, 感觉已经不再是问题, 但是在我不了解LINUX的配制的时候, 我的问题是蛮多的:
1. 如何往配置选项中加入自己定义的配制选项 从而让自己的驱动模块可以让用户通过配置菜单来选择, 让自己的代码被编译进内核
2. 为什么很多的选项都看不到
3. 当我将显卡的FRAMEBUFFER驱动编译进内核后, 如何让它开启
问题1: 其实很简单, 在LINUX下每一个模块下面都有一个config.in的文件, 就是这个文件控制着每一个LINUX模块的编译选项, 要加入自己的配置选项, 就在这个里面, 照着样子加.
问题2. 在相应模块下的config.in, 控制着具体有哪些选项可选, 会根据相应的配制, 显示下一级的相应配置, 因此针对不同的平台,不同的板子, 你能够看到的子选项是不一样的, 所以当我在EP9302的板子上, 想看到FRAMEBUFFER选项的时候, 一个都看不到,当初我最开始弄不明白这个简单问题, 苦恼了一段时间, 没有想到这一层, 现在想清了, 这么easy...
注:有关LINUX的配制方面, 我找到一篇很好的介绍文件, 大家可以看看:
Linux内核配置系统浅析
http://www.ibm.com/developerworks/cn/linux/kernel/l-kerconf/index.html
问题3. 开启FRAMEBUFFER支持, 在PC上的LINUX下来说是比较EASY的,在GRUB上只须要在grub.conf文件有关内核位置那一行示加上vga=0x317(具体数字代表模式可以查看Documentation/FB下面文档),但是在嵌入式平台下面怎么办呢 参数如何传, 谁来传, 在哪传
文档介绍:
[1]. 经过进一步的了解, 知道在ARM上面的LINUX, 上必须有BOOTLOADER才能够启动内核, 关于这一点大家可以查看内核文档:
/Documentation/arm/Booting
/Documentation/arm/Setup
另外还有几篇介绍BOOTLOADER的文件, 都是在IBM上面的, 那里资源很好, 大家在里面查找更多资源:
[2]. 嵌入式系统 Boot Loader 技术内幕
http://www.ibm.com/developerworks/cn/linux/l-btloader/
[3]. Linux bootloader 编写方法
http://www.ibm.com/developerworks/cn/linux/embed/l-bootloader/index.html
还有一篇更全面的E文文档, 里面介绍了ARM的BOOTLOADER原理, 向内核传递的参数, 以及实现一个简单的BOOTLOADER原型:
[4]. Booting ARM Linux
http://www.simtec.co.uk/products/SWLINUX/files/booting_article.pdf
我想通过这几篇文章, 大家可以了解到以下几点:
1. 为什么要Bootloader---------arm上linux内核, 有别于i386pc上的内核, 因为它没有PC上的硬盘主引导扇区以及BIOS方面的支持, 所以必须有一个Bootloader来完成这个事.
2. Bootloader主要做什么-------主要就是配置内存,初始化硬件环境,这部分工作可以等同为PC上的BIOS做的工作; 还有就是引导内核到正确位置, 设置内核的参数区, 跳转入内核执行.
现在回过头讲如何在打开FRAMEBUFFER支持的问题, 进和了解内核我们知道内核的参数有好些, 与FB相关的参数就是:
#define ATAG_VIDEOLFB 0x54410008
struct tag_videolfb {
u16 lfb_width;
u16 lfb_height;
u16 lfb_depth;
u16 lfb_linelength;
u32 lfb_base;
u32 lfb_size;
u8 red_size;
u8 red_pos;
u8 green_size;
u8 green_pos;
u8 blue_size;
u8 blue_pos;
u8 rsvd_size;
u8 rsvd_pos;
};
但是有关这个参数, 我还没有更深入的理解, 我发觉很少有BOOTLOADER在这里传递了这个参数, 有待进一步了解.另外还有一个参数就是:
/* command line: /0 terminated string */
#define ATAG_CMDLINE 0x54410009
struct tag_cmdline {
char cmdline[1]; /* this is the minimum size */
};
这也是内核参数区中的一个参数, 这个参数一般有一个默认值, 如果在配制内核的时候打开了这个支持的话, 有关这个参数可以看内核文档:
/Documentation/kernel-parameters.txt
这个参数命令行可是支持相当的广的, 我们的FB的支持选项就是"video=", 如果在命令行中加入video=EP93xx, 就是告诉内核我们使用的是EP93XX的FB驱动.
2007/05/16
理解Linux的配置文件, 增加Lanrry显示的相关配置选项
今天可以说是比较顺利吧, 没有留下太多的郁闷, 碰到了不少问题, 也解决了一些问题, 但还是有不少不懂的问题.
一扫前几天的郁闷, 又换了台机器, 如果大家一路看过我的日记的话, 应该知道这是第三台机器了, 不知道是机器太破, 还是我的运气实在的不好, 一路过来碰到这么多的破机器!!!!
因为前面那台机器死机的问题, 不知道是我安装的Fodera 5 的问题还是机器的风扇,硬盘,还是光驱的问题, 总之在LINUX状态经常的死,特别是我在MAKE LINUX的内核后, 多半会死, 死多了还会导致启动LINUX时中途就死了, 要多启动好几次;但是在WINDOWS系统下, 死的时候很少, 不过今天也碰到一次了, 我在COPY网络上另一台机上的文件时, 因为文件很大,所以居然死了一次...
总之是问题相当的多, 我在前面都已经说过那些问题了, 现在不再重复了...
而且我下载了Debian 4来安装时, 也是在安装基本系统那一节就进行不下去, 说是执行什么出错, 搞了几次还是那样, 没办法...
中午的时候, 就终于换了机子了, 即第三台机器, 这个机器倒是很好的, 风扇转速不高, 噪声好小, 几乎听不到, 于是就安装Debain 4, 我一来是想验证一下到底我刻录的安装盘有没有问题, 二来也想体验一下这个LINUX的发行版...
差不多四十多分钟就装好了, 一路顺利, 没有出错, 进入系统后, 居然不让ROOT用户登录图形系统, 郁闷, 于是用了另一个用户, 但是进去什么也做不了, 文件也不能创建, 于是在网上找找, 原来是在"登录设置"中要设置成ROOT用户可以登录图形系统...
现在开始准备LINUX的编译环境, 把工具以及源码开发包都COPY过来了, 结果搞了开始就出问题了....
1. 在ROOT用户下找不到.bash_profile文件, 这个文件要修改一下, 设置一下PATH路径, 让编译的工具路径不用每次设置, 结果在DEBIAN 4下怎么都找不到这个文件, 查找也找不到..
2. 手工设置了路径, 然后配置LINUX时, 说什么"gcc command not found", 好奇怪, 为什么是GCC, 而且根据提示, 好象说什么没有配置平台什么的, 这样第一步的make menuconfig都进行不下去了, 不知何故..
于是掉过头来, 再次安装FC 5, 这次安装也差不多四十分钟, 等得还是很郁闷的, 一边看书一边等...
[关于DEBIAN上的问题, 目前还不清楚原因, 留待日后再回过头来看看是什么原因, 相信肯定是有不了解的原因在内,由此也可以LINUX在不同环境下配置编译的问题是多样的]
等到安装完成后, 一路编译, 基本没有出错, 但是总在最后链接的时候, 报告一些变量找不到定义, 经常一阵分析, 原来是缺少键盘映象的相关定义,后面查知了这几个文件编译进去内核的开关, 于是自己在.config文件中加入, 谁知结果还是一样的, 郁闷了一会儿,才搞清楚我又犯了先前的错误, 如果配置选项不属于你指定的处理器配置, 你千万不要自己去修改.config文件, 你那样修改来打开配置是不行的,只能通过去修改config.in文件, 打那些配置选项加入到你的处理器当中...
具体过程如下:
EP9302这个开发板本身是没有LCD支持的, 现在我要为它增加LCD方面的支持,借助的是EP9312等有LCD支持的配制, 然后修改相应的EP93xxfb.c这个LCD驱动,就能完成EP9302的FB驱动, 通过分析总结以及尝试, 必须如下修改配制:
1.在linux-2.4.21/drivers/video/config.in文件中,增加 "$CONFIG_ARCH_EP9302" = "y"-o /内容, 这样才make menuconfig时才能看到framebuffer相关的选项, 否则无法看到ep9302相关"ConsoleDriver"下的Framebuffer配置选项.
if [ "$CONFIG_ARCH_EP9307" = "y" -o /
"$CONFIG_ARCH_EP9312" = "y" -o /
"$CONFIG_ARCH_EP9302" = "y" -o /
"$CONFIG_ARCH_EP9315" = "y" ]; then
bool ' EP93xx Frame Buffer support' CONFIG_FB_EP93XX
else
define_bool CONFIG_FB_EP93XX n
fi
2. inux-2.4.21/drivers/char/config.in, 如下如下内容, 即增加相关Lanry显卡的显示模式以及颜色深度的配置.
# houhh 20070608...
if [ "$CONFIG_ARCH_EP9302" = "y" ]; then
bool ' EP93xx Lanrry Frame Buffer support' CONFIG_FB_EP93XX_LANRRY
else
define_bool CONFIG_FB_EP93XX_LANRRY n
fi
if [ "$CONFIG_FB_EP93XX_LANRRY" = "y" ]; then
choice ' EP93xx Lattice Frame Buffer Display Resolution' /
"640x480 CONFIG_FB_EP93XX_LANRRY_640x480 /
800x600 CONFIG_FB_EP93XX_LANRRY_800x600 /
1024x768 CONFIG_FB_EP93XX_LANRRY_1024x768" 800x600
choice ' EP93xx Lattice Color Depth' /
"8bpp_default CONFIG_FB_EP93XX_LANRRY_8BPP /
8bpp_custom CONFIG_FB_EP93XX_LANRRY_8BPP_CUSTOM /
16bpp_565 CONFIG_FB_EP93XX_LANRRY_16BPP_565" 16bpp_565
fi
这样在配制时你才可以打开SPI-PS2 CONFIG_EP93XX_KBD_SPI/CONFIG_EP93XX_VT选项,其原因是当你打开FRAMEBUFFER支持时, 前提是必须打开CONFIG_VT, 这一点可以去看看:
linux-2.4.21/arch/arm/config.in
这个文件是针对ARM平台的配置, 在里面查找一下CONFIG_VT, 看看就不难理解只有打开了它才能打开FRAMEBUFFER支持, 在MENUCONFIG配置时,打开它后才能看到console driver选项,才能进去配置FRAMEBUFFER支持.
特别说明: 这里再次特别的说明一下, 在进行LINUX配制时, 千万不要自己去手动的找开一些选项的支持,手工的修改.config配置文件是不起任何作用的, 这个文件必须是由配制程序生成,其原因在于配制程序要经过解析你选定的配制选项来生成linux-2.4.21/scripts/mkdep这个产生依赖关系的文件,如果你自己手动修改了.config配置文件, 在执行make dep是会出错的, 这一点我相信初学者是容易出错的, 特引提出来.
小插曲:
前段时间我提到了, 我在装了linux fc5的机器上直接安装WIN系统, 导致了LINUX系统无法启动了, 看不到GRUB菜单了, 于是使用了LINUX的修复盘,作如下操作将LINUX系统找回来了:
1. root (hd0, 5)
2. setup (hd0, 0)
[注: 5是我的LINUX根目录所在盘,至于0我们稍后会讲,正是因为这个浪费我不少时间]

其实正确的操作如下, 差别很小,我回想起,看到网上有人修复GRUB时是如下操作的:
1. root (hd0, 5)
2. setup (hd0)
特别注意这第2条命令, 比起setup (hd0, 0)少了什么, 没有0表示的才是写GRUB到硬盘主引导记录, 不然就是写到第一个分区,我的第一个分区正好是WIN分区,如此修复GRUB后,WIN系统的引导记录就被改写了, 而会直接启动GRUB...
至此,我的WIN系统与LINUX系统终于可以共存了,通过GRUB可以正常的启动我的WIN系统了,LINUX也可以启动了,问题至些我想也不用再多说其它的什么了, 有什么很小的问题也会折磨人的,大家可以想见我在此过程中的痛苦,但是我坚持下来了,平下心静下气,先把问题放下,一时解决不了,日后再来嘛…
2007/05/17
编译MINIGUI的应用示例的交叉编译
今天上午总结分析了一下先前的一些工作, 整理补记了部分的分析日记,不知道对于大家来说,不是不太零乱了 以至于看不懂 或者太长呵呵,我相信如果大家认真仔细去看,一定能够体会的用心.总的来说,是编译了MINIGUI针对ARM库以及示例文件,如Helloworld,button等程序,先说说这个过程中遇到的问题以及收获:
1. 开始的时候,有点迷茫,不知道如何下手,先前虽然编译过PC上运行的MINIGUI程序,但是在PC上编译是很简单的步骤,虽然运行时有些问题,但总体来说整个过程是相当清晰的;编译ARM上跑的MINIGUI,我开始不太清楚的问题是:
[1].minigui须要相应C库文件以及头文件在哪里, 是用什么库 glibc或者ulibc
[2].minigui须要的相应的LINUX系统头文件在哪
[3].如果将MINIGUI配置成ARM平台上运行,以及如何配置成针对具体的操作系统 如传统的LINUX或者是LINUX或者是ECOS
2. 带着以上的几个问题,我精略的查看了MINIGUI源码目录下的配置文件,发现在其build目录下有一些已经配置好的针对LINUX的配置脚本,用的是UCLIB库:
我的MINIGUI版本用的是1.6.2,这个版本没有menuconfig,反而先前的1.3.3版还支持menuconfig,支持图形化的编辑配置,即然没有图形化配置,那就只能自己来动手配置了,查看buildlib-LINUX-arm3000这文件如件, 它是针LINUX的,因此我觉得可以把它拿来作为我们的配制脚本,虽然它的上面指定了LINUX头文件以及UCLIB库文件的路径,但其实我根本没有这些东西,我的系统已经安装好了针对ARM的工具链,包括各自LINUX头文件以及库,因此只要用的是ARM的编译工具,默认用的就是这些,由此解决了MINIGUI所以须的LINUX头文件以及C库的疑问.
3. 直接执行buildlib-LINUX-arm3000这个配置脚本,然后make, make install, MINIGUI的头文件以及生成的静态库文件就被编译到/LINUX/minigui目录下了,当然大家可以修改这个安装目录,我没有修改.
4.开始编译示例,这一步遇到一个奇怪的问题,虽然我也用了buildlib-LINUX-arm3000这个脚本,但是配制的时候,如果用在编译设置(CFLAGS)中加入头文件包含时,就会配置进提示C编译时无法创建执行映象,在LDFLAGS加入库文件包含选项时也是一样,于是就不加它们,结果正常编译通过,生成了MAKEFILE文件,但是编译示例时提示找不到MINIGUI的头文件以及库文件,最后解决办法是手动找到LDFLAGS以及CFLAGS两个选项,手动加入头文件包含与库文件包含:
LDFLAGS = -Wall -L/LINUX/minigui/lib -lc
CFLAGS = -O2 -D__linux__ -I/LINUX/minigui/include
-I/LINUX/minigui/include/ctrl -fno-builtin -nostartfiles -Wall
-Wstrict-prototypes -pipe -D_REENTRANT
其实如果将MINIGUI安装到系统默认的头文件包含路径以及库文件路径(注意是针对ARM平台的,不是编译宿主机平台),就可以不用加这些选项吧,目前还没有试过.
4.运行MINIGUI时,提示非法指令编译好了MINIGUI,因为是带调试信息,而且指定的是静态库,如果觉得在的话,可以自己在连接选项当中将-g参数去掉,这样就会小很多;我编译为一个MINIGUI的示例helloworld,然后通过TFTP下载到板了(前面日记有讲如何建立TFTP以及如何进行下
载), 结果提示非法指令,于是想起来用GDB来调试.
5. 用GDB通过网口调试MINIGUI示例程序开始我想到的是串口,没想到我的网口,真是郁闷,以前用GDB很熟悉了,所以这里就轻车熟路,首先在板子运行 起GDBSERVER:
主机IP:192.168.0.101
板子IP:192.168.0.188
板子上: gdbserver 192.168.0.101:25000 helloworld
开发主机:
arm-linux-gdb
target remote 192.168.0.188:25000
symbol-file /tftpboot/helloworld
经过如上简单操作就可以进行调试了, 首先是开启板子上的调试代理端,等侯主机上的GDB来连接,然后用主机上的GDB来控制板卡上的程序执行,记全在主机上记得加载调试程序的符号信息.
结果弄了半天, 发现根本没有跑到用户程序的main()就提示非法指令了, 实在是搞不懂, 看来只有留待明天才能解决了...
小插曲:
1. 安装升级firefox在官网上下载了最新的2.0.0.3, 解压过后看到了已经编译好的firefox程序, 于是运行,结果提示如下错误:
[root@localhost firefox]# ./firefox
./firefox-bin: error while loading shared libraries: libstdc++.so.5: cannot open shared object file: No such file or directory
先前就下载过一次,当时直接运行没有任何问题,持来这次的LINUX安装少安装了一些什么库文件,于是网上找找,别人提示如下做:
[root@localhost firefox]# yum install libstdc++.so.5
于是在网上下载一段时间,终于安装好这个库文件,运行FIREFOX正常, 以前也这样安装过一次TFTP服务,这次对于LINUX FC5版本的安装总算是再次体会,很好...
2. 安装firefox的FLASH插件
运行时,总是不能显示FLASH插件,老提示要安装,所以郁闷得很,而且自动安装又失败,所以弹出一个下载页面让手动安装,于是下裁下来,一看也是编译好的二进制程序,还有一个安装脚本,一执行提示说请输入FIREFOX的安装路径,输了几次都说不对,于是直接将插件的SO文件COPY到firefox的PLUGIN目录下, 显示FLASH正常,看来FIREFOX的插件支持也是很智能的,直接丢过去就可以了, 不错…
2007/05/18
MINIGUI示例在板子上运行出错的问题
昨天说到在编译MINIGUI的程序到EP9302的平台下运行时,出现错误,下午搞了半天也不知道原因,今天经过仔细的尝试分析,终于知道原因了.
1. 使用GBD调试了好久,把helloworld.c示例改成超级简单的几句代码,无论用不用到MINIGUI的库文件,都会出错,经过这样终于证实错误与MINIGUI的库无关,于是全力查找示例,自己编译了一个最小的示例,打印一句话,用如下命令编译:
arm-linux-gcc -g -o hello hello.c
下载到EP9302下面,是可以正常执行的,经过这样的分析,得知应该是MINIGUI示例编译时,指定的一些参数有问题,仔细打开Makefile文件看,发觉LDFLAGS倒是没什么特别,特别的是在CFLAGS当中的两个参数:
-fno-builtin: 强制不使用内建的一些C库函数,如exit,abort等与系统密切相关的函数.
-nostartfiles: 强制不编译进编译加到用户程序开头的启动代码,负责一些空间分配以及数据初始化工作.
关于这两点,我在GCC手册中查找的,版本是4.4版,直接在GNU的官网上下载的,仔细一看发觉肯定是-nostartfiles的问题,因为我的MINIGUI示例正是根本无法正常执行main函数,我下的断点还没到,程序就出错退出了,于是去掉这个参数,结果可以正常运行MINIGUI示例了.
接着把MiniGUI.cfg这个配置文件也下载到板子上,与示例程序同一路径,MINIGUI正常运行了,仅仅提示说:
[以下为通过minicom终端操作板子上的LINUX系统:]
~ # tftp -g -r button 192.168.0.102
~ # chmod +x button
~ # tftp -g -r MiniGUI.cfg 192.168.0.102
~ # ./button
GALfbcon engine: Error when opening /dev/fb0: No such file or directory.Please check kernel conf.GAL: Init GAL engine failure: fbcon.
Error in step 3: Can not initialize graphics engine!
到这一步已经表明示例正常运行, 仅仅是显卡的FB驱动还没有开启罢了...
搞了老半天,就这么一个参数,因为以前不太熟悉LINUX下的程序的加载运行机制,虽然知道编译器为加入一段启动代码,负责完成传参以及初始化,但是对于LINUX的这个不太yt熟悉,所以一个问题搞了老半天.
另外特别说明一下:我的EP9302是完整的带MMU支持的LINUX平台,因此与LINUX等都是有差别的,我的配制文件是从LINUX的改过来用,所以才会有这个参数,如果你的平台本身就是LINUX,这个参数应该是必须的,对于这个参数要与不要的具体原因, 现在还不太清楚.
2. LINUX启动信息显示到哪去了
前面我就有提到过了,编译成功了LINUX,在EP9302基础上打开了EP93XX的FRAMEBUFFER编译选项,将driver/video/ep93xxfb.c驱动编译到了内核当中,后面下载内核到板子上运行时,原来会打印出很多启动时的信息,现在除了:
Uncompressing Linux........................................... done, booting the kernel.
Please press Enter to activate this console.
然后就没有其它信息, 当时就搞不明白这些消息打印到哪里去了,因为对于LINUX的控制台驱动也不太熟悉, 不明白为什么没有将消息打印输出到串口当中,还须进一步分析. 以弄清楚输出信息的去向问题...
小插曲:
有时候一天要是碰到一个问题, 基本上一天也干不了什么事了,成功的运行了MINIGUI程序板子上后,最后的一步就是移值我们的显卡驱动了,离目标又近了一步,不知还有什么更麻烦的问题,呵呵...
今天查找到几个小命令的用法,相信还是有点用的.
1. 杀进程,因为在板子上运行MINIGUI出错的示例时,进程经常死掉,我用kill pid,居然杀不掉,查找一下用kill -9 pid,正常杀死,原来要加上传给进程的信号量;加上今天调试程序遇到的几个信号量,4是表示非法指令,还有一个段错误的不记得了.
2. 查看模块信息modinfo, 插入模块insmod/modprobe等,以及启动时加载的模块配置文件:
/etc/modprobe.conf
3. 查看系统硬件消息, 开始不知道,以为是当作模块来查看,老是失败,后面得知直接当成文件来查看就行了.
cat /proc/cpuinfo
cat /proc/meminfo
如此即可.
4. 昨天突然觉得在LINUX下不能用IS,虽然装了WINE平台来运行WINDOWS下面的程序,但是好象很不好用,出错是经常的,然且不能进行查找,添加工程文件时特慢,而且易死.
于是想起来,是不是用LINUX下的登录WIN终端的工具,这样不不用跑到另外一台WINXP的机器上了,可是查找了半天,找到了一个winconnect,是一个公司的产品, 只有试用的,安装很方便,可是安装过后连不上.
直接用LINUX下的VNC,好象也不能连接上,不知道是不是WINXP那边没有安装好远程登录支持.
还发现一个rdesktop, 可是DOWN半天下不来,郁闷...
http://www.rdesktop.org/#download
2007/05/25
打开FB支持后启动信息没有显示到超级终端的问题
已经有好几天没有怎么更新日记了, 主要是这几天都是在分析代码为主, 有些问题一两天都分析不清楚,到今天才算大致明白过来,现在总结如下:
1, 关于以前所讲的arm-elf-gcc与arm-linux-gcc的区别:
在以前的日记中有提到过这个问题,现在基本上弄清楚,在网上看过别的贴子才算明白过来,
---arm-linux-gcc 是编译操作系统为linux,目标机为arm的程序.能调用库函数和linux内核函数.
---arm-elf-gcc是编译目标机为arm的程序.只能调用库函数.
如果没有系统的支持,C库当中那些文件操作函数/内存分配函数等与系统相关的函数基本都不能使用了.
2. 以前说到当打打开FB支持之后,启动后输出信息都看不到了,只能看到:
Uncompressing Linux............................................done, booting the kernel.
这个信息是成功加载LINUX内核并解压的提示信息,这段信息的输出还是在没有开启MMU支持直接通过串口输出来的,此时还未进到start_kernel这个内核入口函数,是在decompress_kernel()这个了函数当中输出的解压内核消息,位于/DG930x-linux/edb9302/do_not_edit/linux-2.4.21/arch/arm/boot/compressed/misc.c当中,调用这个解压函数是在内核启动阶段的head.s当中, 具体这部分的分析现在先不讲,以前我就用深入的分析过,主要是要弄明白两个问题:
[1]. 弄明内核生成时的lds链接描述文件的构成,搞清楚内核都有哪几部分构成,分别位于什么位置.
[2]. 弄清楚ARM的一些指令,才能明白过来整体的启动阶段的head.s以及由此如何调用到C(简单的说,在谳用decompress_kernel()时r0,r1,r2等为参数,这是ARM默认的机制).
现在回过头来说,为什么不打开FB支持时,可以看到系统初始化时检测CPU类型/内存状信息,打开之后就看不到
其实进入分析代码之后,才算明白过来,在LINUX当中所以信息的输出(如调用printk())都是由控制台内核部分控制的,主要是在console.c文件当中,因此当一个终端要成为当前的可以接受输出的, 都必须成功调用系统的终端注册,即register_console(), 详细分析这个函数就可以得出如下结论:
[1]. 如果当前还没有已经注册过的终端,那么第一个注册者可以成功注册.
[2]. 如果当前已经有注册过的终端,则会检测在启动时用户是否有指定打开该设备作为终端,如果没有则注册该终端会失败.
[3]. 如果在启动内核时,通过console=ttyAM0这样的形式指定了要打开的终端,则注册该终端时成功,否则失败不能接收到系统打印的启动信息.
经过如上分析,结论是打开FB支持后,虚拟终端支持打开,而且它在串口终端之前先进行注册为系统的终端,因此如果在命令行中没有有效指定要打开的终端,则串口不会在启动时打印出启动信息,启动消息都打印到FB相应的显存中去了,是通过虚拟终端打印过去的,因此在命令行上加上:
先前在RedBoot下启动内核命令为:
exec -r 0x800000 -s 0x600000
必须改为如下才能在启动时也在串口中打印出启动信息:
exec -r 0x800000 -s 0x600000 -c "root=/dev/ram,console=ttyAM0"
3. 如何进行内核的调试:
整个内核分析过程中,肯定要进行内核的调试,下简单的说几点,如何用KGDB进行内核的调试.
[1]. 首先必须更改内核配置,在内核kernel hacking选项中打开GDB支持,具体我后面介绍一个参考文章,可以看看.
[2]. 另外很重要的一点就是必须去掉内核的优化设置,这一点很重要,否则在调试内核的时候可能会看到有些时候代码执行顺序不对, 有些函数内的变量不能进行查看等问题,总之是很奇怪的, 因此要重视这一点:
打开linux-2.4.21/Makefile文件,找到如下行:
CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 /
-fno-strict-aliasing -fno-common
将其中的-O2改成 -O -g, 但千万不要去掉-O2,也不要改成其它的优化级别,包括不能改成-O0, 否则在编译完成后,进行链接时会有错误.这样修改之后就让编译内核时不进行优化了,方便调试了.
[3].在调试内核时,原来的start_kernel()函数如下:
// trap_init(); //houhh 20070524...
setup_arch(&command_line);
trap_init(); //houhh 20070524...
printk("Kernel command line: %s/n", saved_command_line);
parse_options(command_line);
// trap_init();
在上面大家可以看到,trap_init就是开启KGDB调试断点状态的,后面我想调试一下parse_init(),因此将它提前了一些,也可以正常调试,但是如果提到setup_arch之前则是不行的,目前原因还不清楚,但肯定与机器的一些参数相关吧.
[4].KGDB是命令行的,用起来不是很方便,我后面下载了GDB的图形化调试器insight, 其地址在:
http://sourceware.org/insight/
下过来源码后,关于配置要说一点,要配制成针对arm的,执行配置如下:
./configure --TARGET=arm-linux
make
make install
安装完成后我也修了,在看源码方便还是方便了很多,开始调试时,因为我的内核是经过优化的,没有加调试信息,所以用起来感觉就怪怪的,代码执行流程不对,还经常的异常,不过加上调试信息之后,的确方便了很多.
参考资料:
Linux 系统内核的调试
2005 年 12 月 18 日
本文将首先介绍 Linux 内核上的一些内核代码监视和错误跟踪技术,这些调试和跟踪方法因所要求的使用环境和使用方法而各有不同,然后重点介绍三种 Linux 内核的源代码级的调试方法.
http://www.ibm.com/developerworks/cn/linux/l-kdb/
小插曲:
1. 以前有说到过WINE,用它来模拟运行WINDOWS下的程序,后面发现了远程桌面工具rdesktop, 其实这个工具是相当有名的,已经被收进了linux fedora的版本当中.
2. 最近在LINUX下要用ftp,在自己的网站上上传下传东西,发现有一个LINUX下的好用的命令行FTP工具lftp, 如下:
lftp
open ftp://ucgui@ucgui.com
get aaaa.rar
put /aaa.rar
很好用的东西,方便实用,我现在还想找LINUX下的命令行下载工具,好象没有,还要再多找找看.
3. 最近碰到的一个郁闷问题是,我在家里的机器上装了linux fedora 6, 本来是想用上面的eclipse, 谁知居然提示运行出错,好象是JAVA虚拟机没有成功安装,搞了老半天都没有成功安装,以后要现看看.
06月05日
FrameBuffer驱动的编写
一转眼, 又过了好几天了, 这几天对一些问题又终于有了新的认识, 已经基本上可以正常的用FB驱动来运行MINIGUI了, 当然也碰到一些弄不懂的问题, 留待下次再来解决.
我的总体目标在前面已经说过, 是在LINUX下面支持一个显卡的FRAMEBUFFER驱动, 在些过程中介绍初学者如何进入LINUX内核的源码分析, 了解FB驱动的从无到有的知识.
1. 如何打开FB支持
[1] 如何添加FB设备到dev文件系统.
即使已经编译了FB模块到内核当中, 而且已经在命令行中启动了FB, 但是你依然找不到有/dev/fb0这个设备, 你还是无法使用它, 因为你还差一步, 那就是在创建ram盘时, 在dev文件夹下创建/dev/fb0这个设备.
如何创建这个设备
在创建ramdisk磁盘时, 主要使用的是genext2fs这个工具, 这个工具会接收一种文本格式描述的设备列表, 在ep93xx开发包下由device.txt完成这个描述, 其格式基本如下:
#
# Create the necessary character device nodes.
#
#
/dev/mem c640 0 011 0 0 -
/dev/ttyc666 0 050 0 0 -
根据上面的格式, 自己照着加一个FB设备的描述, 然后重新生成ramdisk虚拟盘文件就可以了, 记住fb设备主设备号为29, 你加上的设备名为/dev/fb0, 次设备号为0.
/dev/fb0 c 666 0 0 29 0 0 0 -
[2] 内核启动时如何打开FB支持.
在REDBOOT下启动内核时采用如下命令, 给LINUX内核传递参数:
exec -r 0x800000 -s 0x600000 -c "root=/dev/ram video=ep93xxfb"
上面兰色部分就是传给OS内核的命令行参数, 我们在以前讲过, LINUX有两种给内核传参的方法, 第一种是在BOOTLOADER过程中,将内存信息/虚拟盘信息传给内核, 这些信息以TAGLIST的信息存放在指定的物理内存区域(此时还未开启虚存机制),这个参数地址是可以在配置时指定的; 第二种就是以命令行的方式, 其实命令行也只是第一种传递方法中的一个子项.
注意: 在指定传递命令行参数时, 不同的参数之间用空格间开, 如果是同一个参数的不同选项, 则用","号分开, 否则会导致你的命令行参数无法正确识别, 指定了多个参数也被当做一个命令行参数跳过了.
具体命令行参数的解析是在内核初始化的:
parse_options(command_line);
在解析时, 最重要的完成命令行执行的, 是在checksetup()当中, 这里会检测在链接时形成一个区域, 你可以当它是一个数组, 保存了每个命令行执行的了函数指针以及特征名.诸如video驱动的命令行处理参数如下:
__setup("video=", video_setup);
在video_setup()在中会检测video命令行中所指定的显卡类型, 比较之后就会执行对应显卡的初始化了函数和安装函数.初始化了函数是继续解析些显卡自己的命令行参数, 安装函数则完成具体的显卡初始化工作, 下面详细会讲显卡初始化所要做的几点重要工作.
2. 显卡的初始化的几点工作
显卡一般分好几种不同类型的, 这里我只谈那些有完全总线型的, 不谈那些通过一般I/O口来进行数据传输的.
完全总线型的也分成如下两种:
1, 显卡没有独立的显存, 使用的是分配的系统内存, 然后通过显卡的一些寄存器进行设置, 告知显卡使用哪块系统内存做好显存.
2. 显卡有独立的显存, 而且其内存已经通过硬件连接到了指定的物理内存空间处, 显卡的内存不包括在系统RAM当中, 称作外设内存空间.
这两种情况其实差别不太大, 但是必须要弄清楚, 我所用的LINUX是开启了MMU机制的, 其功能基本与PC上的LINUX是差不多的, 非常强大; 在虚存开启机制下, 所有的内存都是必须经过虚拟射后, 才能进行访问的.
在LINUX启动时, BOOTLOADER会检测到所有的系统RAM内存, 并以传参数告知内核, 如果物理内存是间隔的几块, 就会有几块相应的内存结构信息体, OS内核会对这些内存进行管理, 并将他们映射到虚拟空间.
系统RAM会由OS自己管理并将其映射到虚拟空间, 但是外设的物理内存对于OS来说, 是要本未知的, 所以必须要由自己来完成这个映射,在我们所用的EP93XX的平台上, 除了我自己的显卡内存, 其实还有板卡上面其它外设的物理内存, 如UART口/时钟寄存器等.
[1]. 首先看已经移值完成的系统外设内存的映射
查看EP93XX的数据手册, 可以知道外设的物理内存起始差不多是0x8000 0000, 进行分析EP93XX的平台相关移值代码, 其相关代码位于:
/linux-2.4.21/arch/arm/mach-ep93xx
这个下面有很多关于平台的代码, 我们这里只关注arch.c文件中的:
#ifdef CONFIG_ARCH_EDB9302
MACHINE_START(EDB9302, "edb9302")
MAINTAINER("Cirrus Logic")
BOOT_MEM( CONFIG_EP93XX_PHYS_ADDR, 0x80000000, 0xff000000 )
BOOT_PARAMS( CONFIG_EP93XX_PARAMS_PHYS )
MAPIO(ep93xx_map_io)
INITIRQ(ep93xx_init_irq)
MACHINE_END
#endif
ep93xx_map_io()定义于与arch.c同一文件夹下的mm.c当中, 这里主要描述了如何将外设的物理内存映射到虚拟空间, 提供的是一个回调函数, 会在系统初始化时由内核调用.
/*
* IO Map for EP93xx:
*
* 8000 0000 - 807f ffff = AHB peripherals(8 Meg)
*8080 0000 - 809f ffff = APB peripherals(2 Meg)
*a000 0000 - b000 0000 = PCMCIA space
*/
static struct map_desc ep93xx_io_desc[] __initdata =
{
//
// Virtual Address Physical AddresssSize in BytesDomain RWCB Last
{ IO_BASE_VIRT, IO_BASE_PHYS,IO_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
{ PCMCIA_BASE_VIRT, PCMCIA_BASE_PHYS,PCMCIA_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
LAST_DESC
};
void __init ep93xx_map_io(void)
{
iotable_init(ep93xx_io_desc);
}
简单一点说, 上面就是提供了须要映射的物理外设, 用一个结构体描述了外设的物理基址以及要映射到的虚拟地址, 系统初始化时会调用它, 如下:
Init.c (//tsclient/root/dg930x-linux/edb9302/do_not_edit/linux-2.4.21/arch/arm/mm)
paging_init()中:
if (mdesc->map_io)
mdesc->map_io();
[2]. 如何映射自己的显卡相关使用的外设内存.
上面详细的指出了系统已经支持的基础外设是如何完成内存映射的, 我们就大概明白了这个过程, 进行自己的显卡外设内存的处理基本上就是小事情了:
显卡实际物理内存地址0x1000 0000, 大小为0x20 0000, 显卡内存之后就是相关的一些寄存器的地址以及调色板,我们在映射的时候可以一次性完成, 因为他们在物理内存上是连续的, 映射完成之后的虚拟地址空间也是连续的,所以他们之间的相对偏移与没有完成映射时是一样的.
#define LCD_CS1_REG (IO_BASE_VIRT |0x00080004) // lcd cs1...
// define offset...
#define LCD_CONTROL_SRAM_REG 0x00200008 // lcd sram init control reg...
#define LCD_COMMAND_REG 0x00200006 // lcd command reg...
#define LCD_CONTROL_REG0x0020000e// lcd control reg...
#define LCD_DISPMODE_REG0x00200012// lcd display mode reg...
#define LCD_PAGE_REG0x00200000// lcd current page num reg...
#define LCD_NULLDELAY_REG0x0020001f// for delay...
#define LCD_COLOR_REG0x00200010// color reg......
#define LCD_FB_REG_ADDR0x10200000
#define LCD_FB_REG_LEN 0x400
#define LCD_FB_PHYS_ADDR0x10000000
#define LCD_FB_PHYS_LEN0x200000+LCD_FB_REG_LEN
#define LCD_FB_PAL_ADDR0x10200200
#define LCD_FB_PAL_LEN 0x200
如上所示, 只须用:
ioremap(LCD_FB_PHYS_ADDR, LCD_FB_PHYS_LEN);
即完成了显卡外设内存到虚拟空间的转换, 这样就可以供内核访问显卡的物理内存了, 不过这里特别指出LCD_CS1_REG,这个寄存器是系统本身的一个总线设置寄存器, 它的映射已经由[1]中所说的系统外设映射时完成了, 所以直接计算出他的虚拟地址即可,可须再次进行映射了.
3. 显卡驱动就算初步可以跑了.
理解了以上部分, 再加上自己显卡的硬件初始化部分, 重新编译内核后, 写一个测试程序, 基本就可以正常的使用显卡驱动了, 我现在已经成功的运行起MINIGUI了, 剩下的一些工作就是完成一些IOCTRL, 来支持显卡的一些模式的设置工作.
内核与Framebuffer编译完成后,启动如下:
load -r -v -b 0x800000 -h 192.168.0.100 ramdisk.gz
load -r -v -b 0x80000 -h 912.168.0.100 zImage
exec -r 0x800000 -s 0x600000 -c "root=/dev/ram console=ttyAM0 video=latticefb"
总结: 基本上上面这些东西是初学者比较困或的地方, 觉得对外设的物理内存到底是如何管理不太清楚,我开始也没搞清楚外设内存会不会由BOOTLOADER检测出来传给OS, 让OS来完成到虚存的映射,所以当时还去详细分析了REDBOOT的启动代码中有关内存检测那一部分, 不过后面发觉外设内存各种各样,估计不会象一般内存一样由BOOTLOADER来管理.
原创粉丝点击