
Ldd
文章平均质量分 72
请叫我四哥
人生会碰到好多事,好事,坏事.
展开
-
内核中与驱动相关的内存操作之六(vmalloc)
vmalloc是在整个虚拟空间分配出一段内存,它所面向的处理对象是CPU整个虚拟内存空间,而kmalloc是CPU的逻辑地址空间.逻辑地址空间也是"虚拟"的,只不过它和物理地址空间保持着线性关系的一种"虚拟地址空间",可以说,逻辑地址是虚拟地址的一个子集.1.原型: 2.参数说明: 3.返回值: 4.应用场景: 5.实例:原创 2014-03-18 16:00:46 · 870 阅读 · 0 评论 -
内核中与驱动相关的内存操作之十三(/dev/mem)
在不少平台,包括嵌入式的,如jz4730,pxa-166等都把CPU可访问的整个物理地址空间(逻辑地址空间)映射到用户空间去.其和用户交互的设备节点就是/dev/mem.用户空间通过这个设备节点可以直接访问整个CPU可访的物理地址空间(逻辑地址空间).这里的映射,从宏观来讲,是一种"中介",一种"逻辑转换". 如果我们因为某种特殊需求需要在用户空间编写程序的话(现在有很多用户空间的驱动,原创 2014-03-18 16:10:08 · 1522 阅读 · 0 评论 -
内核中与驱动相关的内存操作之八(面向页的内存分配)
当我们在内核驱动代码中需要用到大量内存时,一般建议采用面向页的内存管理.原创 2014-03-18 16:03:02 · 902 阅读 · 0 评论 -
内核中与驱动相关的内存操作之十一(IO内存)
设备通常会提供一组寄存器用于控制设备、读定设备和获取设备状态,即控制寄存器、数据寄存器和状态寄存器.这些寄存器可能位于I/O空间,也可能位于内存空间.当位于I/O空间时,通常被称为I/O端口,位于内存空间时,对应的内存空间被称为I/O内存.在嵌入式LINUX中,我们接触最多的就是I/O内存:#define request_mem_region(start,n,name) __request_r原创 2014-03-18 16:08:44 · 797 阅读 · 0 评论 -
内核中与驱动相关的内存操作之十(内存屏障)
虽然实际驱动中不常用,但是阅读内核比较深层的代码经常会遇到.为什么存在内存屏障呢?先看一下下面的场景: 编译器和处理器为了提高效率,可能对读和写操作重新进行了排序,例如:在某些处理器上,以下代码: A = 1; B = 2; 有可能在A中存放新值之前就在B中存放新值. 但是,我们在操作内存或者和硬件交互时,常常需要确保一个给定的顺序.原创 2014-03-18 16:05:04 · 740 阅读 · 0 评论 -
内核中与驱动相关的内存操作之二(cache)
ARM处理器的主频比较高,而一般的主存储器的主频比较低.这样,如果指令和数据都存放在主存储器中,主存储器的速度将会严重制约整个系统的性能.为解决这一矛盾,引入了高速缓冲存储器(cache)和写缓冲区(write buffers).它位于主存储器和CPU之间,用来提高存储系统的性能的一种策略.其流程如下:CPUCache/WriteBufferRAM 1.高速缓冲存储器和写原创 2014-03-18 15:57:16 · 840 阅读 · 0 评论 -
内核中与驱动相关的内存操作之十七(DMA)
DMA,即Direct Memory Access,直接内存访问.主要是考虑到CPU和外设之间拷贝大量数据时提升性能的一种硬件策略.原创 2014-03-18 16:16:23 · 2979 阅读 · 0 评论 -
内核中与驱动相关的内存操作之十五(标准I/O)
标准IO又叫缓存IO,内核默认的就是标准IO机制.大多数文件系统的默认I/O操作都是缓存 I/O,比如用户将要写到磁盘的数据会被标准IO缓存,在一定的时机内核会把缓冲的数据写到物理磁盘上.其思想框架如下图所示: 标准IO有以下优点:•缓存 I/O 使用了操作系统内核缓冲区,在一定程度上分离了应用程序空间和实际的物理设备;•缓存 I/O 可以减少读盘的次数,从而提高性能;原创 2014-03-18 16:13:45 · 927 阅读 · 0 评论 -
内核中与驱动相关的内存操作之十四(直接I/O)
1.直接IO的宏观思想: 直接I/O,它是指数据可以直接在磁盘和应用程序地址空间进行传输,而不用路由内核提供的数据缓冲区.宏观框架示意图如下:2.直接IO出现的原因: 标准I/O即缓冲I/O,大多数文件系统的默认操作就是标准I/O.它的存在,缓冲了应用程序到实质物理设备的数据,内核会根据一定的时机更新到实质的物理设备和应用程序空间里面去.像一些应用程序,它有原创 2014-03-18 16:11:02 · 1021 阅读 · 0 评论 -
内核中与驱动相关的内存操作之七(slab)
slab分配器,是内核为了达到高效利用内存的一种管理算法,它以牺牲一些内存空间的代价,收获了代码在时间上的利益. 1.slab的动机: 在操作系统动作过程中,经常会涉及到大量对象的重复生成、使用与释放.在LINUX系统中所用到的对象,比较典型的例子是inode、task_struct等.这些大量的常用的对象如果每次都要从无到有生成、投入使用、使用完再释放,类似这样的操作频率很高.原创 2014-03-18 16:01:20 · 1353 阅读 · 0 评论 -
内核中与驱动相关的内存操作之十二(mmap)
mmap是标准的用户空间的系统调用API.最为常见的就是用户空间对LCD的操作.mmap允许用户直接对硬件设备实现直接访问操作,因此,其效率是很高的.要正确使用mmap机制,首先重温一下VMA.原创 2014-03-18 16:09:15 · 1134 阅读 · 0 评论 -
内核中与驱动相关的内存操作之四(常用结构体)
我去年买了个表.原创 2014-01-22 14:09:28 · 1791 阅读 · 0 评论 -
内核中与驱动相关的内存操作之三(内存模型)
1 页内核把物理页作为内存管理单元.大多数32全体系结构支持4KB的页.从虚拟内存角度来说,页就是最小单位.struct page结构体定义于中: Page结构与物理页相关的,而并非与虚拟页相关.因此,该结构对页的描述只是短暂的.即使页中所包含的数据继续存在,由于交换等原因,它们可能不再和同一个page结构关联.内核仅仅用这个数据结构来描述当前时刻在相关的物理页存放的东西.这种数据结构原创 2014-03-18 15:59:15 · 947 阅读 · 0 评论 -
内核中与驱动相关的内存操作之十六(异步I/O)
1.异步IO: 异步IO机制是指:一旦设备就绪,则主动通知应用程序,这样应用程序就不需要查询设备状态了.当设备就绪条件满足时,设备驱动发一个信号给对应的用户空间程序即可.对关设备是否可操作内核提供了三套机制:阻塞IO、非阻塞IO(poll)、异步通知.主要特性如下:原创 2014-03-18 16:14:11 · 1007 阅读 · 1 评论 -
内核中与驱动相关的内存操作之一(MMU)
我去年买了个表.原创 2014-03-18 15:56:55 · 1259 阅读 · 0 评论 -
基于步进电机在LINUX平台下的调试(之二)
之前在用户空间用操作gpio实现控制步进电机的功能原创 2014-05-19 16:56:34 · 2618 阅读 · 0 评论 -
基于步进电机在LINUX平台下的调试(之一)
工作接到一个项目是需要原创 2014-05-04 11:59:45 · 4392 阅读 · 0 评论 -
内核中与驱动相关的内存操作之九(重映射)
ioremap()函数也是需要建立新的页表,但是不会分配内存.它的功能是将一个物理地址转换成内核需要的虚拟地址(逻辑地址),从而实际硬件的操作.其相反的动作为iounmap(). 以S3C2440的RTC驱动为例:struct platform_device s3c_device_rtc = { .name = "s3c2410-rtc", .id原创 2014-03-18 16:04:10 · 875 阅读 · 0 评论 -
内核中与驱动相关的内存操作之五(kmalloc)
在内核空间里面获取一段内存区域,最常用到的API就是kmalloc.1.原型(lk2.6.22)如下:static inline void *kmalloc(size_t size, gfp_t flags) 2.参数说明:size: 要分配内存空间的大小,以字节为单位.flags: 分配标志,用来控制kmalloc的行为.主要如下:原创 2014-03-18 15:59:51 · 2669 阅读 · 0 评论 -
LINUX中时间相关的概念与操作
一切东西离开了时间便失去了其存在的意义,内核也不例外.下面是经常在内核驱动中经常谈及到的时间的概念和具体的操作应用.1.HZ: HZ在内核中表征时钟中断间隔.与具体体系结构相关.可以理解为"秒".经常用它来派生更短的延时,如毫秒.如下: #define TIMEOUT_WIEGAND HZ/100 表示10毫秒. 它也常和ji原创 2013-12-16 11:16:46 · 968 阅读 · 0 评论 -
设备文件指针操控llseek
llseek主要用来操作文件的指针.其实质是内核依赖filp->f_ops执行文件的定位. 1.原型:loff_t (*llseek)(struct file *,loff_t,int); 各参数意义如下:原创 2013-12-13 21:55:01 · 2279 阅读 · 0 评论 -
MINI2440+UDA1341TS分析之二
LINUX内核存在着音频子系统,其代码是平台无关,其逻辑也已经为我们搭建好.我们一般重点工作便是用平台相关信息去初始化这个子系统.比如我们在S3C2440+UDA1341TS便需要把主控端(S3C2440的音频硬件子系统)和设备UDA1341TS的CODEC相关的信息代入到内核的音频子系统当中去. 下面罗列出SOC端及DEV端的平台设备相关性的代码. 1.S3C2440主原创 2013-10-24 17:15:05 · 1142 阅读 · 0 评论 -
MINI2440+UDA1341TS分析之一
开发板MINI2440上的音频系统为S3C2440+UDA1341TS.原理图如下:原创 2013-10-22 18:06:28 · 2770 阅读 · 0 评论 -
基于MINI2440分析LINUX内核的GPIO子系统分析
MINI2440是基于三星S3C2440平台的DEMO板.作为一个SOC,其引脚都有很多复用功能,如一般的GPIO,特定外设的功能引脚,如IIC的CLK引脚.分析其引脚的配置以作笔记. 1.core_initcall(s3c24xx_gpiolib_init): 内核的设计思想,一是喜欢把某个设备打包成结构体;二是尽可能的分离平台相关的代码,使其更具可移植性.原创 2013-10-09 23:10:11 · 1456 阅读 · 1 评论 -
LINUX下的LCD子系统分析
LINUX下的帧缓冲是LINUX视频系统的核心,其重大意义在于使得开发人员可以与平台无关的方式编写应用程序和较高内核层的程序.从而使得内核的帧缓冲接口允许应用程序与底层图形硬件的变化无关.也就是说,只要应用程序和显示器驱动程序遵循缓冲接口,应用程序可以不用改变就可以在不同类型的视频硬件上运行.其框架图如下: 下面以MINI2440为实例进行分析. 1.平原创 2013-10-04 16:51:57 · 1509 阅读 · 0 评论 -
LINUX下IIC子系统分析
LINUX平台下IIC子系统的经典分布图如下:下面主要针对内核中IIC新模式(new style)进行分析. 下面以S3C2440平台搭载的24C08进行整个LINUX IIC子系统的分析. 1.如何生成用户空间的设备节点: 1-1.24c08驱动端: 24c08的驱动代码位于drivers/misc/eeprom/at24.c原创 2013-09-08 23:57:11 · 2850 阅读 · 0 评论 -
LINUX下input子系统分析
LINUX下input子系统的经典图如下: 我们习惯于一种思维,便人从用户空间的系统调用到实质的硬件结果.先从宏观框架上自下至上分析这个过程.上述中注意三个椭圆的意义: Input driver:具体的设备驱动,如s3c2410ts.c; Event handler:能够处理具体设备的事件驱动,如通用事件驱动evdev.c、触摸屏事件驱动tsdev.c、鼠标事件驱原创 2013-08-20 20:26:24 · 1351 阅读 · 0 评论 -
LINUX下可加载模块的几个工具
当我们在make menuconfig把一些源码文件以作为编译控制项时,表示不编译内核,而是以模块(.ko)存在.此时,要生成.ko模块文件,需要借助下面的命令:bash> cd /usr/src/linux-X.Y.Zbash> make modules 上述命令帮助我们生成目标内核的.ko模块文件.如果需要安装.ko文件,则需要借助下面的命令:bash>make modu原创 2013-08-03 15:35:21 · 1715 阅读 · 0 评论 -
LINUX下串行设备驱动程序
在嵌入式或PC我们经常会遇到串行子系统,常遇到的场合如下:通过RS-232串行链路运行终端会话;通过拔号、小区蜂窝或软件调制解调器连接到因特网;和触摸控制器、智能卡、蓝牙芯片或红外dongle等使用串行传输方式的设备接口;使用USB-串口端口的转换器模拟串行端口;通过RS-485通信,RS-485在RS-232的基础上支持多个节点,传输距离更远,抗噪性能更强.1.LINUX下串行设备驱原创 2013-08-01 17:34:39 · 3031 阅读 · 0 评论 -
Linux下华为3g模块e220上网
1.插入e220,通过lsusb命令查看e220识别情况:(设备id)2.通过id查询文件(查看内核是否支持)3.可以看到内核支持e220(在内核源码包中找到usb的3G驱动文件 drivers/usb/serial/option.c)4.插入相关模块(有依赖关系)5.下载e220驱动程序: http://oozie.fm.interia.pl/src/hu转载 2013-08-02 02:13:41 · 677 阅读 · 0 评论 -
Alsa驱动移植
作者:程姚根,华清远见嵌入式学院讲师。一. 下载alsa所需要的库和测试alsa的测试工具,此次使使用的是alsa-lib-1.0.24.1.tar.bz2、alsa-utils-1.0.24.2.tar.bz2。二. 默认情况下内核已经支持alsa驱动,保险情况下先去确认一下,如下图:Device Drivers ---> Sound card suppor转载 2013-05-16 10:25:48 · 784 阅读 · 0 评论 -
LINUX驱动子系统设计的粗糙模型
LINUX内核的特点: 1).可移植性很强.从其支持众多的CPU及DEMO板可以知道; 2).上层APP的统一. 这两点都得归功于内核设计的思想模型,简而言之就是驱动子系统的功劳. 最粗糙、最笼统的LINUX内核驱动设计思想模型图如下: 下面分析上述的框架图: (1).直接面向用户空间(UserSpace)的是内核驱动子系统,比原创 2013-10-23 10:34:48 · 694 阅读 · 0 评论 -
MINI2440+UDA1341TS分析之三
我们已经大体知道与平台相关并且知道内核音频子系统所需要的数据结构.接下来我们将根据函数调用流程看一下平台相关的代码是如何和内核音频子系统交互的. 1.static int s3c24xx_uda134x_probe(struct platform_device *pdev) MINI2440音频驱动的入口在sound/soc/s3c24xx/s3c24xx_uda1原创 2013-11-02 14:56:40 · 1547 阅读 · 0 评论 -
MINI2440+DM9000网络驱动分析之四
从之三的dm9000_probe()函数,到下面代码为止便进入内核网络子系统: ret = register_netdev(ndev); 从大的角度看,此函数有两个功能:一是命名我们的PHY的名字,如eth0、eth1等;二是通过函数register_netdevice(dev)正式入驻内核网络子系统. 1. err = dev_alloc_name(dev,原创 2013-11-18 11:58:41 · 918 阅读 · 0 评论 -
非阻塞(轮询)I/O操作poll()和select()
除了阻塞之外,内核还提供了非阻塞(即轮询)策略.具体的程序表现为poll、select和epoll系统调用.上层应用程序最常见的是select()函数.而对应的底层函数即为poll()函数.1.poll()简介: poll()函数原型如下:unsigned int (*poll)(struct file *filp,poll_table *wait) 各参数如下:fil原创 2013-12-05 20:46:32 · 1227 阅读 · 0 评论 -
异步通知fasync
最基本的read()和write()函数实现的数据最基本的交互.等待队列实现了读写阻塞策略,针对一些比较长时间才可以获取资源的设备进程进行休眠处理进而优化了系统资源的利用率;poll机制可以实现设备的监听,可以进一步提高读写机制的命中时机.而异步通知则类似于硬件上的中断,当设备资源准备就绪,向指定进程发送信号,从而唤醒进程对此信号进行处理. 从而言之,读写是必须的核心动作,而wait_q原创 2013-12-12 16:04:00 · 1908 阅读 · 0 评论 -
阻塞I/O(等待队列)
在实际驱动程序中,我们经常会遇到这种情景:当我们进行读写操作时,设备或数据还没准备就绪时,我们应该提供一种策略来把当前进程让出CPU从而避免资源上的浪费.当设备或数据就绪时再唤醒这个进程,从而使得系统资源的优化利用.这种策略,就是睡眠和唤醒.1.睡眠与唤醒: 当进程进入睡眠状态后,将从调度器的运行队列上移除,只有等待某时机唤醒再投放到调度器的运行队列上参与竞争得到运行.原创 2013-12-04 22:40:22 · 1361 阅读 · 0 评论 -
字符设备之ioctl
1.ioctl()函数的存在意义: 除了简单的数据传输之外,大部分设备还可以执行一些其他的动作,比如用户空间请求设备锁门、弹出介质、改变波特率等.这些动作可以通过ioctl来实现.2.ioctl()函数的参数说明: ioctl()函数原型如下:int (*ioctl)(struct inode *inode,struct file *filp,unsigne原创 2013-12-04 00:03:43 · 1054 阅读 · 0 评论 -
fsync
fsync在LINUX中的意义在原创 2013-12-10 21:45:20 · 6202 阅读 · 0 评论 -
字符设备之read和write
1.内核空间的read()和write(): read和write最大的意义是完成用户空间到内核空间的数据交互.其原型如下:ssize_t read(struct file *filp,char __user *buff,size_t count,loff_t *offp);ssize_t write(struct file *filp,const char __use原创 2013-12-02 22:24:07 · 2194 阅读 · 0 评论