×

linux驱动开发教程

linux驱动开发教程(如何自学linux驱动开发,做驱动开发需要哪些方面的知识)

admin admin 发表于2023-04-14 17:15:49 浏览36 评论0

抢沙发发表评论

本文目录

如何自学linux驱动开发,做驱动开发需要哪些方面的知识


做嵌入式应用的话一般的编程就可以了。那么嵌入式驱动开发与内核开发的话就需要学习多个方面的知识。我就把这方面的要求给你交流一下:
(一家之言啊,自己多年从事嵌入式开发的一点感悟)
嵌入式驱动开发需要了解的知识大概有以下几类:
1 嵌入式操作系统驱动框架。每一个操作系统都有自己的构架,应该了解驱动在整个系统中的具体位置与构建驱动程序的主要事项
2 总线知识,比如PCI、USB总线。
3 芯片知识。驱动其实就是对设备上一些寄存器的配置、CPU与设备本身的通讯以及对不同命令的处理
4 要做好驱动,必须对所使用的CPU体系结构有一个比较深刻的认识
5 C++基本用不上,主要是C和汇编。
6 做驱动最好要懂内核调试(比如说linux)

linux如何开发显卡驱动


linux系统是需要安装显卡驱动的。

安装Linux系统并不难,参考用户手册很容易完成。在安装系统以前,看过很多的文章,知道Linux系统对硬件的兼容性很差,安装驱动会非常费事。

1.安装完成后,进入桌面,听到悦耳的启动音乐想起-——系统兼容声卡;无线网卡找到TP-LINK——兼容无线网卡。只是屏幕图像很差,系统本身的显示驱动严重不兼容显卡,因此必须重新安装显卡驱动。

2.在Linux系统下安装显卡驱动比较麻烦,网上浏览,不成功的例子很多。不像Windows只要点击鼠标即刻完成。

3.下面是我安装显卡驱动的详细步骤记录:

1,下载适合我笔记本电脑的显卡驱动,需要注意的是必须是For Linux。我的显卡是ATI Mobility Radeon HD2400,上ATI官方网站找到显卡驱动:ati-driver-installer-8-4-x86.x86_64.run

2,将下载的驱动ati-driver-installer-8-4-x86.x86_64.run拷贝至Linux的Root/下;

3,进入/etc/inittab/ ,修改启动级别为3(id:5:initdefault中的5改为3);重新启动,....Looin:root,进入文字模式;

4,输入:sh ati-driver-installer-8-4-x86.x86_64.run;

5,进入安装提问模式,一直点OK;安装结束;

6,进入文字模式下,输入:startx,进入Linux X-windows桌面;

7,进入/etc/x11/xorg.conf文件,修改下列这段:

Section “Device“Driver “fglrx“ ——将vesa改为fglrxIdentifier “Card0 for screen 0“EndSection再添加下列一段:Section “Extensions“Option “Composite“ “0“EndSection

8.进入显示设置:在显卡驱动下拉菜单中找到fglrx,点击确定。

9.进入/etc/inittab文件,改回启动级别为5;

电脑重启(因为是X-windows桌面,用reboot命令重启电脑)

启动后,系统进入KDE桌面,这样显卡驱动就完全安装完成了,


如何系统的学习Linux驱动开发


在学习之前一直对驱动开发非常的陌生,感觉有点神秘。不知道驱动开发和普通的程序开发究竟有什么不同;它的基本框架又是什么样的;他的开发环境有什么特殊的地方;以及怎么写编写一个简单的字符设备驱动前编译加载,下面我就对这些问题一个一个的介绍。

一、驱动的基本框架

1.  那么究竟什么是驱动程序,它有什么用呢:

l     驱动是硬件设备与应用程序之间的一个中间软件层

l 它使得某个特定硬件能够响应一个定义良好的内部编程接口,同时完全隐蔽了设备的工作细节

l     用户通过一组与具体设备无关的标准化的调用来完成相应的操作

l 驱动程序的任务就是把这些标准化的系统调用映射到具体设备对于实际硬件的特定操作上

l     驱动程序是内核的一部分,可以使用中断、DMA等操作

l     驱动程序在用户态和内核态之间传递数据

2.  Linux驱动的基本框架

3.  Linux下设备驱动程序的一般可以分为以下三类

1)        字符设备

a)         所有能够象字节流一样访问的设备都通过字符设备来实现

b)        它们被映射为文件系统中的节点,通常在/dev/目录下面

c)        一般要包含open read write close等系统调用的实现

2)        块设备

d)        通常是指诸如磁盘、内存、Flash等可以容纳文件系统的存储设备。

e)         块设备也是通过文件系统来访问,与字符设备的区别是:内核管理数据的方式不同

f)         它允许象字符设备一样以字节流的方式来访问,也可一次传递任意多的字节。

3)        网络接口设备

g)        通常它指的是硬件设备,但有时也可能是一个软件设备(如回环接口loopback),它们由内核中网络子系统驱动,负责发送和接收数据包。

h)        它们的数据传送往往不是面向流的,因此很难将它们映射到一个文件系统的节点上。

 

二、怎么搭建一个驱动的开发环境

因为驱动是要编译进内核,在启动内核时就会驱动此硬件设备;或者编译生成一个.o文件, 当应用程序需要时再动态加载进内核空间运行。因此编译任何一个驱动程序都要链接到内核的源码树。所以搭建环境的第一步当然是建内核源码树

1.       怎么建内核源码树

a) 首先看你的系统有没有源码树,在你的/lib/ modules目录下会有内核信息,比如我当前的系统里有两个版本:

#ls /lib/ modules

2.6.15-rc7  2.6.21-1.3194.fc7

查看其源码位置:

## ll /lib/modules/2.6.15-rc7/build

lrwxrwxrwx 1 root root 27 2008-04-28 19:19 /lib/modules/2.6.15-rc7/build -》 /root/xkli/linux-2.6.15-rc7

发现build是一个链接文件,其所对应的目录就是源码树的目录。但现在这里目标目录已经是无效的了。所以得自己重新下载

b)下载并编译源码树

有很多网站上可以下载,但官方网址是:

使用之后肯定是要释放的,其方式如下:

void unregister_chrdev_region(dev_t first, unsigned int count);

6)         

2.         驱动程序的二个最重要数据结构

1)         file_operation

倒如字符设备scull的一般定义如下:
struct file_operations scull_fops = {
.owner =  THIS_MODULE, 
 .llseek =  scull_llseek, 
 .read =  scull_read, 
 .write =  scull_write, 
 .ioctl =  scull_ioctl, 
 .open =  scull_open, 
 .release =  scull_release,  
};

file_operation也称为设备驱动程序接口

定义在 , 是一个函数指针的集合. 每个打开文件(内部用一个 file 结构来代表)与它自身的函数集合相关连( 通过包含一个称为 f_op 的成员, 它指向一个 file_operations 结构). 这些操作大部分负责实现系统调用, 因此, 命名为 open, read, 等等

2)         File

定义位于include/fs.h

struct file结构与驱动相关的成员

l         mode_t f_mode      标识文件的读写权限

l         loff_t f_pos           当前读写位置

l         unsigned int_f_flag 文件标志,主要进行阻塞/非阻塞型操作时检查

l         struct file_operation * f_op  文件操作的结构指针

l         void * private_data 驱动程序一般将它指向已经分配的数据

l         struct dentry* f_dentry  文件对应的目录项结构

3.         字符设备注册

1)        内核在内部使用类型 struct cdev 的结构来代表字符设备. 在内核调用你的设备操作前, 必须编写分配并注册一个或几个这些结构. 有 2 种方法来分配和初始化一个这些结构.

l             如果你想在运行时获得一个独立的 cdev 结构,可以这样使用:

struct cdev *my_cdev = cdev_alloc();

my_cdev-》ops = &my_fops;

l             如果想将 cdev 结构嵌入一个你自己的设备特定的结构; 你应当初始化你已经分配的结构, 使用:

void cdev_init(struct cdev *cdev, struct file_operations *fops);

2)        一旦 cdev 结构建立, 最后的步骤是把它告诉内核, 调用:

int cdev_add(struct cdev *dev, dev_t num, unsigned int count);

说明:dev 是 cdev 结构, num 是这个设备响应的第一个设备号, count 是应当关联到设备的设备号的数目. 常常 count 是 1, 但是有多个设备号对应于一个特定的设备的情形.

3)        为从系统去除一个字符设备, 调用:

void cdev_del(struct cdev *dev);

4.         open 和 release


想学习Linux 驱动,需要什么知识


首先,接触linux操作系统,在你的电脑上装一个linxu操作系统(建议ubuntu,比
较友好),熟悉经常要用的命令,熟悉环境(建议看“鸟哥的linux私房菜”)。
其次,阅读经典书籍是不可少的,建议先看ldd前四章,大概了解linux驱动的框架
,驱动是做什么的,该如何写驱动,那本书上有一些例子,可以在你的电脑上编译
,执行看看。后面的章节在结合自己的情况而定。
第三,建议阅读ulk(understanding the linux kernel)所有的内容,了解linux
内核的一些基本知识,在心中建立一个框架,不必完全懂,深入了解就好,以后经
常翻翻,受益无穷!
第四,别着急,这才是你真的进入linux驱动的第一步,花点钱买个开发板吧,然
后了解代码的编译,下载,看看板子的datasheet,针对自己感兴趣的深入研究。
建议学习流程,led灯控制---tp---i2c总线-----lcd-----camera----flash----
wifi/bt等。因为这个里面牵涉了甚多内核的子系统(input,v4l2,fb等
),所以可能要多话时间看代码,了解代码的框架,设计的思想等,只要一步一个
脚印,一定会有所成。
第五,因为现在的移动设备大多数都是android的了,所以你就要看看linux
kernel在android的作用,然后往上看看,看看hal层的代码,这些在调试中都是需
要的,如果有兴趣,更加可以看看framework的代码了,学习android一些工作机制
,类似于surfaceflinger,audioflinger等等。。
《linux就该这么学》免费提供最新Linux技术教程书籍,为开源技术爱好者努力做
得更多更好

linux驱动开发要有哪些基础


需要一定的努力才可以学好:
Linux设备驱动是linux内核的一部分,是用来屏蔽硬件细节,为上层提供标准接口的一种技术手段。为了能够编写出质量比较高的驱动程序,要求工程师必须具备以下几个方面的知识:
1、 熟悉处理器的性能
如:处理器的体系结构、汇编语言、工作模式、异常处理等。对于初学者来说,在还不熟悉驱动编写方法的情况下,可以先不把重心放在这一项上,因为可能因为它的枯燥、抽象而影响到你对设备驱动的兴趣。随着你不断地熟悉驱动的编写,你会很自然的意识到此项的重要性。
2、掌握驱动目标的硬件工作原理及通讯协议
如:串口控制器、显卡控制器、硬件编解码、存储卡控制器、I2C通讯、SPI通讯、USB通讯、SDIO通讯、I2S通讯、PCI通讯等。编写设备驱动的前提就是需要了解设备的操作方法,所以这些内容的重要程度不言而喻。但不是说要把所有设备的操作方法都熟悉了以后才可以写驱动,你只需要了解你要驱动的硬件就可以了。
一、掌握硬件的控制方法
如:中断、轮询、DMA 等,通常一个硬件控制器会有多种控制方法,你需要根据系统性能的需要合理的选择操作方法。初学阶段以实现功能为目的,掌握的顺序应该是,轮询-》中断-》DMA。随着学习的深入,需要综合考虑系统的性能需求,采取合适的方法。
二、良好的GNU C语言编程基础
如:C语言的指针、结构体、内存操作、链表、队列、栈、C和汇编混合编程等。这些编程语法是编写设备驱动的基础,无论对于初学者还是有经验者都非常重要。
三、 良好的linux操作系统概念
如:多进程、多线程、进程调度、进程抢占、进程上下文、虚拟内存、原子操作、阻塞、睡眠、同步等概念及它们之间的关系。这些概念及方法在设备驱动里的使用是linux设备驱动区别单片机编程的最大特点,只有理解了它们才会编写出高质量的驱动。
四、掌握linux内核中设备驱动的编写接口
如:字符设备的cdev、块设备的gendisk、网络设备的net_device,以及基于这些基本接口的framebuffer设备的fb_info、mtd设备的mtd_info、tty设备的tty_driver、usb设备的usb_driver、mmc设备的mmc_host等。

如何编写Linux 驱动程序


以装载和卸载模块为例:

1、首先输入代码

#include 《linux/init.h》

#include 《linux/module.h》

2、然后输入下方的代码:

static int my_init(void)

 {

                       return  0;

 }

static void my_exit(void) 

3、然后在输入下方的代码:

{

                       return; 

}

module_init(my_init); 

module_exit(my_exit);这样就完成了。