Ⅰ 如何学习嵌入式linux驱动程序开发求解
2. 编一应用程序,可以用makefile跑起来
3. 学会写驱动的makefile
4. 写一简单char驱动,makefile编译通过,可以insmod, lsmod, rmmod. 在驱动的init函数里打印hello world, insmod后应该能够通过dmesg看到输出。
5. 写一完整驱a动, 加上read, write, ioctl, polling等各种函数的驱动实现。 在ioctl里完成从用户空间向内贺毕孙核空间传递结构体的实现。
6. 写一block驱动, 加上read,write,ioctl,poll等各种函数实现。
7. 简单学习下内存管理, 这个是最难的,明白各种memory alloc的函数实现细节。这是linux开发的基本功。
8. 学习锁机制的应用,这个不是最难的但是最容易犯错的,涉及到很多同步和并发的问题。
9. 看内核中实际应用的驱动代码。 你会发现最基本的你已经知道了, 大的框架都是数闷一样的, 无非是read, write, ioctl等函数的实现, 但里面包含了很多很多细小的实现细节是之前不知道的。 这时候就要考虑到很多禅链别的问题而不仅仅是基本功能的实现。例如:凌阳教育嵌入式linux培训课程的第四阶段:嵌入式微处理器及Linux设备驱动开发的学习主要是通过:ARM硬件接口原理,嵌入式Linux设备驱动开发,嵌入式Linux高级驱动程序设计这三大块深入浅出的学习驱动程序开发。让学员熟悉Linux的内核机制、驱动程序与用户级应用程序的接口,掌握系统对设备的并发操作。
Ⅱ Linux设备驱动开发入门与编程实践的目录
第1章嵌入式Linux系统开发概述
1.1嵌入式系统概述
1.1.1你身边的嵌入式系统
1.1.2什么是嵌入式系统
1.1.3嵌入式系统的发展
1.1.4嵌入式系统市场规模
1.1.5嵌入式系统发展趋势和面临的挑战
1.2嵌入式操作系统
1.2.1嵌入式操作系统的特昌芦点
1.2.2嵌入式操作系统发展概述
1.2.3Linux操作系统特点
1.2.4嵌入式Linux系统的特点
1.2.5国外嵌入式Linux发展现状
1.2.6国内嵌入式Linux发展现状
1.3ARM处理器平台介绍
1.3.1嵌入式处理器特点与分类
1.3.2ARM处理器介绍
1.3.3ARM体系结构
1.4嵌入式Linux的体系结构分析
1.4.1嵌入式系统的体系结构
1.4.2硬件抽象层的Linux
1.5基本编辑器vi的使用
1.5.1进入和退出vi
1.5.2vi的基本编辑命令
1.5.3vi的高级编辑命令
1.6高级编辑器Emacs的使用
1.6.1Emacs的启动与退出
1.6.2Emacs的基本操作
1.6.3Emacs的高级命令
1.7编译器GCC的使用
1.7.1GCC简介
1.7.2GCC的编译过程
1.7.3GCC的常用模式
7.4GCC的常用选项
1.7.5GCC的警告功能
1.8调试器GDB的使用
1.8.1GDB的调试过程
1.8.2GDB的基本命令
1.8.3GDB的高级命令
1.9Make工程陆迅枯管理器
1.9.1Make管理器简介
1.9.2Makefile的描述规则
1.9.3一个简单示例
1.9.4Make如何工作
1.9.5指定变量
1.9.6自动推导规则
1.9.7另类风格的Makefile
1.9.8清除工作目录过程文件
1.10本章小结
第2章嵌入式Linux内核分析与移植
2.1Linux内核版本
2.1.1日新月异的Linux内核版本
2.1.2Linux2.4内核特性
2.1.3Linux2.6内核针对嵌入式系统的改进
2.2Linux操作系统内核结构分析
2.2.1Linux核心源程序的文件组织结构
2.2.2Linux的内核组成
2.2.3Linux内核进程管理工作机制
2.2.4Linux内存管理工作机制
2.2.5Linux虚拟文件系统工作机制
2.2.6进程间通信
2.3搭建嵌入式Linux系统开发环境
2.3.1嵌入式平台介绍
2.3.2嵌入式Linux系统的组成及设计步骤
2.3.3嵌入式Linux开发工具链
2.4Linux内核配置基础
2.4.1Linux内核所支持的配置方式
2.4.2makemenuconfig配置方法
2.4.3Linux2.4内核配置文件config .in介绍
2.4.4Linux2.6内核Kconfig文件的用法
2.4.5Kconfig文件配置实例
2.5Linux内核配置选项
2.5.1Generalsetup
2.5.2Loadablemolesupport
2.5.3Processortypeandfeatures
2.5.4Networkingsupport
2.5.5DeviceDrivers
2.6Linux内核编译基础
2.6.1Linux内核编译基本步骤
2.6.2Rules.make文件用法
2.6.3Makefile配置文件的用法
2.6.4配置、编译Linux内核命令说明
2.6.5Linux内核配置编译实例
2.7Linux内核移植
2.7.1Bootloader简介
2.7.2引导程序原理
2.7.3内核移植及代码分析
2.7.4VIVI结构分析
2.7.5VIVI移植实现
2.8本章小结
第3章Linux设备驱动程序开发概述
3.1Linux系统设备概述
3.1.1字符设备
3.1.2块设备
3.1.3网络设备
3.1.4Linux设备驱动程序的共性
3.2设备驱动程序的概念
3.3设备驱动程序与内核的接口
3.4内核为驱动程序提供的支持
3.4.1内存分配函数
3.4.2DMA
3.4.3I/O端口
3.4.4打印函数
3.5主要数据结构
3.5.1structdevicestruct
3.5.2structfileoperations
3.5.3structinode
3.6模块化的概念
3.7内存管理问题
3.7.1Linux内核对内存的管理方早洞法
3.7.2kmalloc()和kfree()
3.7.3面向页的分配技术
3.7.4vmalloc()和相关函数
3.8中断响应和处理
3.8.1中断处理机制
3.8.2中断处理的数据结构
3.8.3中断处理中的3个重要概念
3.8.4申请和释放中断
3.8.5自动检测中断号
3.8.6快/慢速中断处理
3.8.7实现中断处理程序
3.8.8驱动程序下半部的设计
3.8.9安装共享的处理程序
3.9I/O端口
3.10DMA处理
3.11时间流
3.11.1时钟的申请与释放
3.11.2实现延迟
3.11.3任务队列
3.12编写、编译和调试
3.13本章小结
第4章Linux字符设备驱动程序开发
4.1Linux字符设备驱动程序结构
4.2字符设备驱动的相似点
4.3主设备号和次设备号
4.4字符设备驱动程序的组成
4.5字符驱动程序模型
4.6可靠性机制
4.7文件操作
4.8字符设备驱动程序中用到的主要数据结构
4.9字符设备的注册和注销
4.10使用内存和读写I/O端口
4.11字符设备驱动程序中用到的主要函数
4.12chardevxxx设备的驱动程序设计
4.13Linux2.6内核下的字符设备驱动介绍
4.13.1cdev结构体
4.13.2分配和释放设备号
4.13.3file_operations结构体
4.13.4字符设备驱动模块加载与卸载函数
4.13.5字符设备驱动的file_operations结构体中成员
4.14globalmem设备驱动
4.14.1头文件、宏及设备结构体
4.14.2加载与卸载设备驱动
4.14.3读写函数
4.14.4seek函数
4.14.5globalmem的ioctl()函数
4.14.6ioctl()命令
4.14.7预定义命令
4.14.8使用文件私有数据
4.14.9globalmem驱动在用户空间的验证
4.15本章小结
第5章基于DSP的PCI图像采集卡驱动程序
5.1PCI总线介绍
5.1.1PCI总线概述
5.1.2PCI局部总线概述
5.1.3PCI局部总线的特点
5.1.4PCI总线信号
5.1.5PCI总线命令
5.1.6PCI总线配置空间
5.1.7PCI总线配置过程
5.1.8PCI总线的传输控制
5.2DSP图像卡的PCI接口设计
5.2.1系统结构介绍
5.2.2PCI2040的基本特点
5.2.3PCI2040芯片的功能单元
5.2.4PCI2040配置流程
5.2.5PCI总线与DSP的接口实现
5.2.6串行E2PROM的初始化
5.3DSP图像卡驱动程序实例分析
5.3.1主要的数据结构
5.3.2驱动程序流程
5.3.3初始化设备模块
5.3.4打开设备模块
5.3.5数据读写和控制信息模块
5.3.6中断处理模块
5.3.7释放设备模块
5.3.8卸载设备模块
5.4本章小结
第6章音频接口设计与Linux驱动程序
6.1嵌入式音频系统简介
6.1.1S3C2410微处理器简介
6.1.2S3C2410微处理器的结构框图及其特性
6.1.3系统设计概述
6.1.4系统时钟电路
6.1.5S3C2410存储控制器介绍
6.1.6SDRAM电路
6.1.7Flash缓冲电路设计
6.1.8NORFlash电路
6.1.9NANDFlash接口电路
6.1.10IIS数字音频电路
6.1.11串口电路
6.1.12JTAG接口电路
6.1.13LCD和触摸屏接口电路
6.2UDA1341TS芯片设备驱动程序设计
6.2.1UDA1341TS芯片介绍
6.2.2驱动程序中file_operations数据结构
6.2.3驱动程序的加载和卸载
6.3SOUND驱动的实现
6.3.1SOUND设备的打开和释放
6.3.2定义SOUND设备的读写函数
6.3.3SOUND设备的控制操作处理
6.3.4SOUND设备驱动程序的其他部分
6.3.5Mixer驱动的实现
6.4本章小结
第7章显示设备接口设计与Linux驱动程序
7.1嵌入式显示系统简介
7.2显示驱动的基础与原理
7.2.1时序信号
7.2.2TFTLCD的驱动技术
7.2.3TFTLCD驱动电路
7.2.4像素值的属性
7.2.5像素深度、像素值与颜色的映射关系
7.2.6像素值与显示内存的映射关系
7.2.7调色板的原理
7.2.8调色板的作用
7.2.9彩色LCD显示驱动的原理
7.3软、硬件平台简介
7.3.1硬件开发平台
7.3.2软件平台
7.3.3软件开发环境
7.4基于PXA255的显示功能的硬件实现
7.4.1PXA255处理器介绍
7.4.2PXA255的LCD控制器的特点
7.4.3LCD控制器的使用
7.4.4LCD控制寄存器配置
7.4.5设定DMA通道
7.4.6Sony彩屏的特性
7.4.7LCD与处理器的硬件连接方案
7.5显示驱动开发介绍
7.5.1显示驱动与字符设备的关系
7.5.2显示驱动的发展
7.5.3当前显示驱动的不足
7.6基于PXA255的显示驱动的实现
7.6.1显示驱动的系统分析
7.6.2驱动上层文件的功能
7.6.3驱动底层文件的功能
7.6.4驱动程序底层文件实现的基础
7.7基于PXA255的显示功能的软件方案
7.7.1上层文件的实现
7.7.2底层文件的实现方案
7.7.3驱动底层文件的实现
7.7.4针对XScale架构中其余处理器的移植
7.8本章小结
第8章ARMLinux块设备驱动程序开发
8.1块设备驱动程序开发概述
8.1.1块设备特点
8.1.2块设备基于缓冲区的数据交换
8.1.3块设备读写请求
8.1.4块设备驱动程序模型
8.1.5基于内存的块设备驱动程序
8.2Linux块设备驱动结构
8.2.1block_device_operations结构体
8.2.2gendisk结构体
8.2.3request与bio结构体
8.3块设备驱动主要函数
8.3.1块设备驱动程序的注册与注销
8.3.2Linux块设备驱动模块加载与卸载
8.3.3块设备的打开与释放
8.3.4块设备驱动的ioctl函数
8.3.5块设备驱动I/O请求处理
8.4RAMDISK驱动开发实例
8.4.1RAMDISK的硬件原理
8.4.2RAMDISK驱动模块加载与卸载
8.4.3RAMDISK设备驱动block_device_operations及成员函数
8.5IDE硬盘设备驱动开发实例
8.5.1IDE硬盘设备原理
8.5.2IDE硬盘设备驱动block_device_operations及成员函数
8.5.3IDE硬盘设备驱动I/O请求处理
8.5.4在内核中增加对新系统IDE设备的支持
8.6本章小结
第9章嵌入式Linux网络设备驱动程序开发
9.1嵌入式以太网基础知识
9.1.1以太网技术及其嵌入式应用
9.1.2嵌入式系统中主要处理的网络协议
9.1.3ARP(AddressResolutionProtocol)地址解析协议
9.1.4IP(InternetProtocol)网际协议
9.1.5TCP(TransferControlProtocol)传输控制协议
9.1.6UDP(UserDatagramProtocol)用户数据包协议
9.2基于CS8900A芯片的设备驱动设计
9.2.1CS8900A芯片结构
9.2.2CS8900A芯片特性
9.2.3CS8900A芯片工作原理
9.2.4CS8900A芯片工作模式
9.2.5网络设备驱动程序基本结构
9.3基于Linux的网络设备驱动开发常用的数据结构
9.3.1数据结构structnet_device
9.3.2数据结构structsk_buff393
9.4网络驱动程序的实现模式及系统调用方法
9.4.1网络驱动程序的实现模式与模块化
9.4.2内存获取与释放
9.4.3链路状态改变系统调用
9.4.4与网络层交互数据包的函数
9.5网络驱动程序的基本方法
9.5.1网络驱动程序的结构
9.5.2初始化(Initialize)
9.5.3打开(open)
9.5.4关闭(close)
9.5.5发送(hard_start_xmit)
9.5.6接收(reception)
9.5.7中断处理(interrupt)
9.5.8硬件帧头(hard_header)
9.5.9地址解析(XARP)
9.5.10参数设置和统计数据
9.5.11多播(set_multicast_list)
9.6本章小结
第10章嵌入式LinuxUSB驱动程序设计基础
10.1USB总线协议背景知识
10.1.1USB协议的产生
10.1.2USB的特点
10.1.3USB的广泛应用
10.1.4USB在嵌入式设备中的应用
10.1.5计算机常用外部总线比较
10.2USB总线技术介绍
10.2.1USB系统拓扑结构
10.2.2USB总线逻辑结构
10.2.3USB总线特性介绍
10.2.4USB总线电气机械特性
10.2.5USB的即插即用特性
10.2.6鲁棒性的实现
10.2.7USB电源管理
10.2.8总线通道
10.2.9传输协议
10.2.10传输类型
10.2.11设备框架
10.2.12USB主机协议
10.3LinuxUSB子系统结构
10.3.1文件系统
10.3.2Linux中USB子系统的软件结构及实现
10.3.3LinuxUSB内核的主要数据结构
10.3.4USB内核函数接口分析
10.4本章小结
第11章USB接口系统软件设计
11.1USB系统软件设计概述
11.1.1主机端设备驱动程序
11.1.2主机控制器驱动程序
11.1.3设备端驱动程序
11.1.4数据管道和数据块结构
11.2USB设备端软件的开发
11.2.1USB设备通用模块的软件开发
11.2.2USB设备协议模块的软件开发
11.2.3控制端点处理程序
11.2.4协议层程序
11.3USB主机端软件开发
11.3.1Linux内核对USB规范的支持
11.3.2USB时序
11.3.3主机控制器驱动程序设计
11.3.4主机控制器的初始化和管理
11.3.5传输执行和资源调度
11.3.6主机控制器的中断处理
11.3.7虚拟根集线器
11.3.8主机控制器驱动程序的任务
11.3.9URB在驱动软件中运作
11.3.10主机端设备驱动程序
11.4本章小结
第12章OTG驱动功能模块的设计与实现
12.1OTG概述
12.1.1OTG特性简介
12.1.2A设备事件
12.1.3B设备事件
12.1.4状态机
12.1.5SRP
12.1.6HNP
12.2设备模块的设计与实现
12.2.1USB设备的状态
12.2.2OTG驱动功能模块的设计
12.2.3ISP1761结构
12.2.4HAL的设计和实现
12.2.5HCD的设计和实现
12.2.6USBD接口模块
12.2.7ISP1761读写操作模块
12.2.8HCD初始化模块
12.2.9中断管理模块
12.2.10根集线器模块
12.2.11数据传输模块
12.2.12设备模块的设计和实现
12.2.13OTGFSM的设计和实现
12.3本章小结
Ⅲ 求《Linux设备驱动开发详解4.0》全文免费下载百度网盘资源,谢谢~
《Linux设备驱动开发详解4.0》网络网盘pdf最新全集下载:
链接: https://pan..com/s/1wxaYK87l11FDur15aS6FTQ
Ⅳ 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 嵌入式操作系统驱动框架。每一个操作系统都有自己的构架,应该了解驱动在整个系统中的具体位置与构建驱动程序的主要事项
2 总线知识,比如PCI、USB总线。
3 芯片知识。驱动其实就是对设备上一些寄存器的配置、CPU与设备本身的通讯以及对不同命令的处理
4 要做好驱动,必须对所使用的CPU体系结构有一个比较深刻的认识
5 C++基本用不上,主要是C和汇编。
6 做驱动最好要懂内核调试(比如说linux)
Ⅵ linux设备驱动有什么实际应用说详细一点,它的现状和发展方向如何
对于一些使用了linux系统的设备,linux设备驱动就为用户提供了使用外围设备的方法。
Ⅶ Linux设备驱动的Linux设备驱动的重点、难点
(1)编写Linux设备驱动要求工程师有非常好的硬件基础,懂得SRAM、Flash、SDRAM、磁盘的读写方式,UART、I2C、USB等设备的接口以及轮询、中断、DMA的原理,PCI总线的工作方式以及CPU的内存管理单元(MMU)等。
(2) 编写Linux设备驱动要求工程师有非常好的C语言基础,能灵活地运用C语言的结构体、指针、函数指针及内存动态申请和释放等。
(3)编写Linux设备驱动要求工程师有一定的Linux内核基础,虽然并不要求工程师对内核各个部分有深入的研究,但至少要明白驱动与内核的接口。尤其是对于块设备、网络设备、Flash设备、串口设备等复杂设备,内核定义的驱动体系架构本身就非常复杂。
(4) 编写Linux设备驱动要求工程师有非常好的多任务并发控制和同步的基础,因为在驱动中会大量使用自旋锁、互斥、信号量、等待队列等并发与同步机制。
Ⅷ 《Linux设备驱动开发详解基于最新的Linux4.0内核》pdf下载在线阅读,求百度网盘云资源
《Linux设备驱动开发详解》(宋宝华)电子书网盘下载免费在线阅读
资源链接:
链接:https://pan..com/s/1ddjTHycqTk3yYQDr-raoKw
书名:Linux设备驱动开发详解
作者:宋宝华
豆瓣评分:6.5
出版社:机械工业出版社
出版年份:2015-8
页数:618
内容简介:
对于嵌入式工程师来说,进入更高阶段后,学习Linux设备驱动开发无疑就是职业生涯的一次“重生”。这是因为Linux设备驱动开发不仅仅涉及操作系统的转换,开发方式的转换,更重要的是思维上的转变。对于Linux这样一个复杂系统,如何从复杂的代码中抓住设备驱动开发的关键是任何一个Linux设备驱动开发者入门时需要面对的挑战。除了知识、工具之外,往往还需要思路上的指导。本书不但帮助Linux设备驱动开发的初学者厘清必要的概念,还从具体的实例、设备驱动开发的指导原则循序渐进地引导读者渐入学习佳境。为了让读者能够达到Linux设备驱动开发的至臻境界,作者更是从软件工程的角度抽象出设备驱动开发的一般思想。毫无疑问,本书将成为读者学习Linux设备驱动开发过程中的一座“灯塔”。
作者简介:
宋宝华,
Linux布道者,知名嵌入式系统专家,《Essential Linux Device Drivers》译者。作为最早从事Linux内核与设备驱动研究的专家之一,他在众多国内外知名企业开展Linux技术培训。他也是一位活跃的Linux开发者和深度实践者,为Linux官方内核贡献了大量的Linux源码并承担代码审核工作。至今已向Linux官方内核提交逾数万行代码和几百个补丁。他的《Linux设备驱动开发详解》系列书在嵌入式Linux开发者中有口皆碑,是众多Linux书籍中为数不多的畅销书。
Ⅸ 如何系统的学习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/ moles目录下会有内核信息,比如我当前的系统里有两个版本:
#ls /lib/ moles
2.6.15-rc72.6.21-1.3194.fc7
查看其源码位置:
## ll /lib/moles/2.6.15-rc7/build
lrwxrwxrwx 1 root root 27 2008-04-28 19:19 /lib/moles/2.6.15-rc7/build -> /root/xkli/linux-2.6.15-rc7
发现build是一个链接文件,其所对应的目录就是源码树的目录。但现在这里目标目录已经是无效的了。所以得自己重新下载
b)下载并编译源码树
有很多网站上可以下载,但官方网址是:
http://www.kernel.org/pub/linux/kernel/v2.6/
下载完后当然就是解压编译了
# tar –xzvf linux-2.6.16.54.tar.gz
#cd linux-2.6.16.54
## make menuconfig (配置内核各选项,如果没有配置就无法下一步编译,这里可以不要改任何东西)
#make
…
如果编译没有出错。那么恭喜你。你的开发环境已经搭建好了
三、了解驱动的基本知识
1.设备号
1)什么是设备号呢?我们进系统根据现有的设备来讲解就清楚了:
#ls -l /dev/
crwxrwxrwx 1 root root1,3 2009-05-11 16:36 null
crw------- 1 root root4,0 2009-05-11 16:35 systty
crw-rw-rw- 1 root tty5,0 2009-05-11 16:36 tty
crw-rw---- 1 root tty4,0 2009-05-11 16:35 tty0
在日期前面的两个数(如第一列就是1,3)就是表示的设备号,第一个是主设备号,第二个是从设备号
2)设备号有什么用呢?
l传统上,主编号标识设备相连的驱动.例如, /dev/null和/dev/zero都由驱动1来管理,而虚拟控制台和串口终端都由驱动4管理
l次编号被内核用来决定引用哪个设备.依据你的驱动是如何编写的自己区别
3)设备号结构类型以及申请方式
l在内核中, dev_t类型(在中定义)用来持有设备编号,对于2.6.0内核, dev_t是32位的量, 12位用作主编号, 20位用作次编号.
l能获得一个dev_t的主或者次编号方式:
MAJOR(dev_t dev); //主要
MINOR(dev_t dev);//次要
l但是如果你有主次编号,需要将其转换为一个dev_t,使用: MKDEV(int major, int minor);
4)怎么在程序中分配和释放设备号
在建立一个字符驱动时需要做的第一件事是获取一个或多个设备编号来使用.可以达到此功能的函数有两个:
l一个是你自己事先知道设备号的
register_chrdev_region,在中声明:
int register_chrdev_region(dev_t first, unsigned int count, char *name);
first是你要分配的起始设备编号. first的次编号部分常常是0,count是你请求的连续设备编号的总数. name是应当连接到这个编号范围的设备的名子;它会出现在/proc/devices和sysfs中.
l第二个是动态动态分配设备编号
int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name);
使用这个函数, dev是一个只输出的参数,它在函数成功完成时持有你的分配范围的第一个数. fisetminor应当是请求的第一个要用的次编号;它常常是0. count和name参数如同给request_chrdev_region的一样.
5)设备编号的释放使用
不管你是采用哪些方式分配的设备号。使用之后肯定是要释放的,其方式如下:
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结构与驱动相关的成员
lmode_t f_mode标识文件的读写权限
lloff_t f_pos当前读写位置
lunsigned int_f_flag文件标志,主要进行阻塞/非阻塞型操作时检查
lstruct file_operation * f_op文件操作的结构指针
lvoid * private_data驱动程序一般将它指向已经分配的数据
lstruct 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 device driver 的概念系统调用是操作系统内核和应用程序之间的接口,设备驱动程序是操作系统内核和机器硬件之间的接口.设备驱动程序为应用程序屏蔽了硬件的细节,这样在应用程判梁序看来,硬件设备只是一个设备文件,应用程序可以象操作普通文件一样对硬件设备进行操作.设备驱动程序是内核的一部分,它完成以下的功能:
1、对设备初始化和释放;
2、把数据从内核传送到硬件和从硬件读取数据;
3、读取应用程序传送给设备文件的数据和回送应用程序请求的数据;
4、检测和处理设备出现的错误.
在Linux操作系统下枯闹有三类主要的设备文件类型,一是字符设备,二是块设备,三是网络设备.字符设备和块设备的主要区别是:在对字符设备发出读/写请求时,实际的硬件I/O一般就紧接着发生了,块设备则不然,它利用一块系统内存作缓冲区,当用户进程对设备请求能满足用户的要求,就返回请求的数据,如果不能,就调用请求函数来进行实际的I/O操作.块设备是主要针对磁盘等慢速设备设计的,以免耗费过多的CPU时间来等待.
已经提到,用户进程是通过设备文件来与实际的硬件打交道.每个设备文件都都有其文件属性(c/b),表示是字符设备还是块设备?另外每个文件都有两个设备号,第一个是主设备号,标识驱动程序,第二个是从设备号,标识使用同一个设备驱动程序的不同的硬件设备,比如有两个软盘,就可以用从设备号来区分他们.设备文件的的主设备号必须与设备驱动程序在登记时申请的主设备号一致,否则用户进程将无法访问到驱动程序.
最后必须提到的是,在用户进程调用驱动程序时,系统进入核心态,这时不再是抢先式调度.也就是说,系统必须在你的驱动程序的子函数返回后才能进行其他的工作.如果你的驱动程序陷入死循环,不幸的是你只有重新启动机器了,然后就是漫长的fsck.
二、实例剖析
我们来写一个最简单的字符设备驱动掘败运程序.虽然它什么也不做,但是通过它可以了解Linux的设备驱动程序的工作原理.把下面的C代码输入机器,你就会获得一个真正的设备驱动程序.
由于用户进程是通过设备文件同硬件打交道,对设备文件的操作方式不外乎就是一些系统调用,如 open,read,write,close…, 注意,不是fopen, fread,但是如何把系统调用和驱动程序关联起来呢?这需要了解一个非常关键的数据结构:
STruct file_operatiONs {
int (*seek) (struct inode * ,struct file *, off_t ,int);
int (*read) (struct inode * ,struct file *, char ,int);
int (*write) (struct inode * ,struct file *, off_t ,int);
int (*readdir) (struct inode * ,struct file *, struct dirent * ,int);
int (*select) (struct inode * ,struct file *, int ,select_table *);
int (*ioctl) (struct inode * ,struct file *, unsined int ,unsigned long);
int (*mmap) (struct inode * ,struct file *, struct vm_area_struct *);
int (*open) (struct inode * ,struct file *);
int (*release) (struct inode * ,struct file *);
int (*fsync) (struct inode * ,struct file *);
int (*fasync) (struct inode * ,struct file *,int);
int (*check_media_change) (struct inode * ,struct file *);
int (*revalidate) (dev_t dev);
}
这个结构的每一个成员的名字都对应着一个系统调用.用户进程利用系统调用在对设备文件进行诸如read/write操作时,系统调用通过设备文件的主设备号找到相应的设备驱动程序,然后读取这个数据结构相应的函数指针,接着把控制权交给该函数.这是linux的设备驱动程序工作的基本原理.既然是这样,则编写设备驱动程序的主要工作就是编写子函数,并填充file_operations的各个域.
下面就开始写子程序.
#include