《linux驱动工程师面试题整理.doc》由会员分享,可在线阅读,更多相关《linux驱动工程师面试题整理.doc(19页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、-作者xxxx-日期xxxxlinux驱动工程师面试题整理【精品文档】1、字符型驱动设备你是怎么创建设备文件的,就是/dev/下面的设备文件,供上层应用程序打开使用的文件?答:mknod命令结合设备的主设备号和次设备号,可创建一个设备文件。评:这只是其中一种方式,也叫手动创建设备文件。还有UDEV/MDEV自动创建设备文件的方式,UDEV/MDEV是运行在用户态的程序,可以动态管理设备文件,包括创建和删除设备文件,运行在用户态意味着系统要运行之后。那么在系统启动期间还有devfs创建了设备文件。一共有三种方式可以创建设备文件。2、写一个中断服务需要注意哪些?如果中断产生之后要做比较多的事情你是
2、怎么做的?答:中断处理例程应该尽量短,把能放在后半段(tasklet,等待队列等)的任务尽量放在后半段。评:写一个中断服务程序要注意快进快出,在中断服务程序里面尽量快速采集信息,包括硬件信息,然后推出中断,要做其它事情可以使用工作队列或者tasklet方式。也就是中断上半部和下半部。第二:中断服务程序中不能有阻塞操作。为什么?大家可以讨论。 第三:中断服务程序注意返回值,要用操作系统定义的宏做为返回值,而不是自己定义的OK,FAIL之类的。3、自旋锁和信号量在互斥使用时需要注意哪些?在中断服务程序里面的互斥是使用自旋锁还是信号量?还是两者都能用?为什么?答:使用自旋锁的进程不能睡眠,使用信号量
3、的进程可以睡眠。中断服务例程中的互斥使用的是自旋锁,原因是在中断处理例程中,硬中断是关闭的,这样会丢失可能到来的中断。4、原子操作你怎么理解?为了实现一个互斥,自己定义一个变量作为标记来作为一个资源只有一个使用者行不行?答:原子操作指的是无法被打断的操作。我没懂第二句是什么意思,自己定义一个变量怎么可能标记资源的使用情况?其他进程又看不见这个变量评:第二句话的意思是:定义一个变量,比如 int flag =0; if(flag = 0) flag = 1; 操作临界区; flag = 0; 这样可否?5、insmod 一个驱动模块,会执行模块中的哪个函数?rmmod呢?这两个函数在设计上要注意
4、哪些?遇到过卸载驱动出现异常没?是什么问题引起的?答:insmod调用init函数,rmmod调用exit函数。这两个函数在设计时要注意什么?卸载模块时曾出现卸载失败的情形,原因是存在进程正在使用模块,检查代码后发现产生了死锁的问题。评:要注意在init函数中申请的资源在exit函数中要释放,包括存储,ioremap,定时器,工作队列等等。也就是一个模块注册进内核,退出内核时要清理所带来的影响,带走一切不留下一点痕迹。6、在驱动调试过程中遇到过oops没?你是怎么处理的?7、ioctl和unlock_ioctl有什么区别?8、驱动中操作物理绝对地址为什么要先ioremap?答:因为内核没有办法
5、直接访问物理内存地址,必须先通过ioremap获得对应的虚拟地址。9、设备驱动模型三个重要成员是?platfoem总线的匹配规则是?在具体应用上要不要先注册驱动再注册设备?有先后顺序没?10、linux中内核空间及用户空间的区别?用户空间与内核通信方式有哪些?11、linux中内存划分及如何使用?虚拟地址及物理地址的概念及彼此之间的转化,高端内存概念?12、linux中中断的实现机制,tasklet与workqueue的区别及底层实现区别?为什么要区分上半部和下半部?13、linux中断的响应执行流程?中断的申请及何时执行(何时执行中断处理函数)?14、linux中的同步机制?spinlock
6、与信号量的区别?15、linux中RCU原理?16、linux中软中断的实现原理?17、linux系统实现原子操作有哪些方法?18、MIPS Cpu中空间地址是怎么划分的?如在uboot中如何操作设备的特定的寄存器?19、linux中系统调用过程?如:应用程序中read()在linux中执行过程即从用户空间到内核空间?20、linux内核的启动过程(源代码级)?21、linux调度原理?22、linux网络子系统的认识?23、linux内核里面,内存申请有哪几个函数,各自的区别?Kmalloc() _get_free_page() mempool_create() 24. IRQ和FIQ有什么
7、区别,在CPU里面是是怎么做的?25. 中断的上半部分和下半部分的问题:讲下分成上半部分和下半部分的原因,为何要分?讲下如何实现?上半部分执行与硬件相关的处理要求快, 而有些驱动在中断处理程序中又需要完成大量工作,这构成矛盾,所以Linux有所谓的bottom half机制,中断处理程序中所有不要求立即完成的,在开中断的环境下,由底半程序随后完成.Linux的底半处理实际上是建立在内核的软中断机制上的.Linux 的底半 机制主要有Tasklet 和 work queue 以及 softirq ( 2.4内核则有BH , Task queue , softirq , tasklet 没有wor
8、k queue),其实底半可以理解成一种工作的延迟。所以实际使用时跟timer机制基本上一个意思。26. 内核函数mmap的实现原理,机制?mmap函数实现把一个文件映射到一个内存区域,从而我们可以像读写内存一样读写文件,他比单纯调用read/write也要快上许多。在某些时候我们可以把内存的内容拷贝到一个文件中实现内存备份,当然,也可以把文件的内容映射到内存来恢复某些服务。另外,mmap实现共享内存也是其主要应用之一,mmap系统调用使得进程之间通过映射同一个普通文件实现共享内存。27. 驱动里面为什么要有并发、互斥的控制?如何实现?讲个例子?28. spinlock自旋锁是如何实现的?自旋
9、锁在同一时刻只能被最多一个内核任务持有,所以一个时刻只有一个线程允许存在于临界区中。这点可以应用在多处理机器、或运行在单处理器上的抢占式内核中需要的锁定服务。这里也介绍下信号量的概念,因为它的用法和自旋锁有相似的地方。linux中的信号量是一种睡眠锁。如果有一个任务试图获得一个已被持有的信号量时,信号量会将其推入等待队列,然后让其睡眠。这时处理器获得自由去执行其它代码。当持有信号量的进程将信号量释放后,在等待队列中的一个任务将被唤醒,从而便可以获得这个信号量。29. 任务调度的机制?30. 嵌入式linux和wince操作系统的特点和特性?31. 嵌入式linux中tty设备驱动的体系结构?3
10、2. 嵌入式设备,为加快启动速度,可以做哪些方面的优化?33. USB设备的枚举过程?(1) Get Device Descriptor。主机的第一个命令要求得到设备描述符,此SETUP 包为8 个字节数据(80,06,00,01,00,00,40,00),发向地址0,端口0。“40”表示返回数据长度最大为40H 个字节。实际上,只返回一个包,即数组DEV_DESC 中的前8 个字节,用于说明设备的描述符的真实长度和设备的类型。(2) Set Address。接着是设置设备地址处理事件,主机发送一个含有指定地址的数据包(00,05,02,00,00,00,00,00),在主机只有一个USB 设
11、备的时候,这个地址一般会是2,最大地址127,USB 协议中可以连接127 个设备。设置地址事件处理结束后,设备进入地址状态,主机以后会在新的指定地址处访问设备。(3) Get Device Descriptor。主机再次发送请求得到设备描述符的数据包(80,06,00,01,00,00,12,00),与上次不同的是,要求的数据的长度是实际的数据长度,同时是发送到Set Address命令所设置的地址。(4) 读取全部Configuration Descriptor。接着主机要求得到设备全部的配置描述符、接口描述符和节点描述符(80,06,00,02,00,00,40,00),由于主机不知道设
12、备描述符的真实长度,因此它要求得到64个字节。(5) Set Interface,主机发送数据包(01,0B,00,00,00,00,00,00),设置接口值为0。(6) Set Conifguration,确定USB设备工作在哪一个配置下。对于U盘设备来说,一般只有1个配置值,其值为01。主机发送数据包(00,09,01,00,00,00,00,00)。(7) 如果以上步骤都正确,主机将找到新设备,并且配置成功,该设备可以正常使用,可以进行后续的U盘枚举过程了。(8) 用busHound观察计算机对于U盘的枚举过程,发现上述步骤后还有一个GetMaxLun的操作,但是实际上对于U盘来说忽略该
13、步骤也没有问题。34. PSRAM、SDRAM、DDR、DDR2的时序特性?35.什么是GPIO?general purpose input/output GPIO是相对于芯片本身而言的,如某个管脚是芯片的GPIO脚,则该脚可作为输入或输出高或低电平使用,当然某个脚具有复用的功能,即可做GPIO也可做其他用途。也就是说你可以把这些引脚拿来用作任何一般用途的输入输出,例如用一根引脚连到led的一极来控制它的亮灭,也可以用一根(一些)引脚连到一个传感器上以获得该传感器的状态,这给cpu提供了一个方便的控制周边设备的途经。如果没有足够多的gpio管脚,在控制一些外围设备时就会力有不逮,这时可采取的方
14、案是使用CPLD来帮助管理。36.触摸屏的硬件原理?触摸屏的主要三大种类是:电阻技术触摸屏、 表面声波技术触摸屏、 电容技术触摸屏。电阻触摸屏的主要部分是一块与显示器表面非常配合的电阻薄膜屏, 这是一种多层的复合薄膜,它以一层玻璃或硬塑料平板作为基层,表面图有一层透明氧化金属 (ITO氧化铟,透明的导电电阻) 导电层,上面在盖有一层外表面硬化处理、光滑防擦的塑料层 、它的内表面也涂有一层ITO涂层 、在他们之间有许多细小的(小于1/1000英寸)的透明隔离点把两层导电层隔开绝缘 。当手指触摸屏幕时,两层导电层在触摸点位置就有了接触,控制器侦测到这一接触并计算出(X,Y )的位置,再根据模拟鼠标
15、的方式运作。这就是电阻技术触摸屏的最基本的原理。表面声波技术是利用声波在物体的表面进行传输,当有物体触摸到表面时,阻碍声波的传输,换能器侦测到这个变化,反映给计算机,进而进行鼠标的模拟。电容技术触摸屏利用人体的电流感应进行工作 。用户触摸屏幕时 ,由于人体电场,用户和触摸屏表面形成以一个耦合电容, 对于高频电流来说,电容是直接导体,于是手指从接触点吸走一个很小的电流37.在Linux C中,ls这个命令是怎么被执行的?使用fork创建一个进程或exec函数族覆盖原进程。38.在一个只有128M内存并且没有交换分区的机器上,说说下面两个程序的运行结果1#define MEMSIZE 1024*1
16、024int count = 0;void *p = NULL;while(1) p = (void *)malloc(MEMSIZE); if (!p) break; printf(Current allocation %d MBn, +count);2while(1) p = (void *)malloc(MEMSIZE); if (!p) break; memset(p, 1, MEMSIZE); printf(Current allocation %d MBn, +count);第一道程序分配内存但没有填充,编译器可能会把内存分配优化掉,程序死循环;第二道,程序分配内存并进行填充,系统
17、会一直分配内存,直到内存不足,退出循环。39.请定义一个宏,比较两个数a、b的大小,不能使用大于、小于、if语句搞的比较复杂。主要思想就是a-b的值的最高位是否为0;但是又得考虑整数溢出的问题,所以很复杂。不知道哪位大侠有更好的办法,指点指点。#include#define ZHENG(i)(i 31)= 0)#define FU(i)(i 31)!= 0)#define COMPARE(a,b)(ZHENG(a)& FU(b)|(ZHENG(a)& ZHENG(b)|(FU(a)&FU(b)&(a)-(b) 31)= 0)void main() int a = 0x80000001; int
18、 b = 0x6FFFFFFF; if(COMPARE(a,b) printf(a = bn); else printf(a bn); 40、LINUX下的Socket套接字和Windows下的WinSock有什么共同点?请从C/C+语言开发的角度描述,至少说出两点共同点。参考答案:第1题,答中一个得5分,答出其它正确答案的,也得5分。a)都基于TCP/IP协议,都提供了面向连接的TCP SOCK和无连接的UDP SOCK。b)都是一个sock结构体。c)都是使用sock文件句柄进行访问。d)都具有缓冲机制。41、请编写一个标准Shell脚本testd,实现如下功能:A、在Linux操作系统启
19、动的时候,自动加载/mnt/test/test程序。B、当test异常退出之后,自动重新启动。C、当test程序重启次数超过100次,自动复位操作系统。假设你所拥有的资源:A、目标机器是一台具有标准shell的嵌入式计算机,CPU为ARM7 56MB,内存16MB,软件环境基于Linux2.6.11和BusyBox1.2构建。B、当前已有11个用户进程在运行,占用了大部分的CPU时间和内存,你可使用的内存只有2MB左右,CPU时间由系统分派。本题是考查LINUX和嵌入式编程功底的,写出程序来的不少,但是95%以上的人竟无视我假设的资源,不知道在重启test程序的时候需要加上一个适当的掩饰时间,
20、以便资源紧张的操作系统有时间回收资源。85%的人不知道写完testd之后,要在init里边加载这个脚本,才能实现启动时自动加载的功能。参考答案:#testd is a daemon script to start an watch the program test#!/bin/sh#load *.so that may needif -r /sbin/ldconfig ; thenldconfigfi#add the libs PATH that may needexport LD_LIBRARY_PATH=/lib#count is the counter of test started t
21、imescount=0#main loopwhile 1 ;do#add execute property for /mnt/test/testchmod +x /mnt/test/test#start test/mnt/test/test#the running times counterlet count=count+1echo test running times is $count#Is test running too many times?if $count -gt 100 ; thenecho Will reboot because of test running too man
22、y timesrebootfi#wait for test stoping.sleep 3done#42.你平常是怎么用C写嵌入式系统的死循环的?43.写一条命令,实现在dir以及其子目录下找出所有包含“hello world”字符串的文件44.下面的两段程序中,循环能否执行?为什么?A: unsigned short i; unsigned short index = 0; for(i = 0; i index-1; i+) printf(“an”); B: unsigned short i; unsigned long index = 0; for(i = 0; i index-1; i+
23、) printf(“bn”); bootloader烧录进去后,上电后串口上没有任何输出,硬件和软件各应该去检查什么? 提示: 1.跑LINUX的系统一般都需要外扩DRAM,一般的系统也经常有NOR或NAND FLASH 476列举最少3种你所知道的嵌入式的体系结构,并请说明什么是ARM体系结构。mov r12, #0x0 ldr r13, =0x30100000mov r14, #4096loop: ldmia r12!, r0-r11 stmia r13!, r0-r11 cmp r12, r14 bl loop48.嵌入式中常用的文件系统有哪些?说出它们的主要特点和应用场合?rGpioB
24、ase的地址是0x56000000,寄存器的015位有效,请写出给外设寄存器高八位(815位)设置成0xc3的代码50.如何编写一个LINUX驱动?提示:主要说字符设备的编写过程 51.简述LINUX驱动中字符设备和块设备的区别?52.试总结单片机底层开发与LINUX驱动开发有哪些异同?53.请从网卡、USB HOST、LCD驱动器、NAND FLASH、WIFI 、音频芯片中选择一个或者2个(可以以具体的芯片为例),对下面的问题做答:1)如果是外部扩展芯片,请说出你用的芯片的型号2)画出上题中你选定相应硬件模块与CPU的主要引脚连线3) 编写上题中你选定相应硬件模块相应LINUX驱动的流程?
25、54、linux驱动分类Linux设备驱动的分类(1)字符设备。(2) 块设备。(3) 网络设备。字符设备指那些必须以串行顺序依次进行访问的设备,如触摸屏、磁带驱动器、鼠标等。块设备可以用任意顺序进行访问,以块为单位进行操作,如硬盘、软驱等。字符设备不经过系统的快速缓冲,而块设备经过系统的快速缓冲。但是,字符设备和块设备并没有明显的界限,如对于Flash设备,符合块设备的特点,但是我们仍然可以把它作为一个字符设备来访问。网络设备在Linux里做专门的处理。Linux的网络系统主要是基于BSD unix的socket 机制。在系统和驱动程序之间定义有专门的数据结构(sk_buff)进行数据的传递
26、。系统里支持对发送数据和接收数据的缓存,提供流量控制机制,提供对多协议的支持。55、信号量与自旋锁自旋锁自旋锁是专为防止多处理器并发而引入的一种锁,它应用于中断处理等部分。对于单处理器来说,防止中断处理中的并发可简单采用关闭中断的方式,不需要自旋锁。自旋锁最多只能被一个内核任务持有,如果一个内核任务试图请求一个已被争用(已经被持有)的自旋锁,那么这个任务就会一直进行忙循环旋转等待锁重新可用。要是锁未被争用,请求它的内核任务便能立刻得到它并且继续进行。自旋锁可以在任何时刻防止多于一个的内核任务同时进入临界区,因此这种锁可有效地避免多处理器上并发运行的内核任务竞争共享资源。事实上,自旋锁的初衷就是
27、:在短期间内进行轻量级的锁定。一个被争用的自旋锁使得请求它的线程在等待锁重新可用的期间进行自旋(特别浪费处理器时间),所以自旋锁不应该被持有时间过长。如果需要长时间锁定的话, 最好使用信号量。但是自旋锁节省了上下文切换的开销。自旋锁的基本形式如下:spin_lock(&mr_lock);/临界区spin_unlock(&mr_lock);因为自旋锁在同一时刻只能被最多一个内核任务持有,所以一个时刻只有一个线程允许存在于临界区中。这点很好地满足了对称多处理机器需要的锁定服务。在单处理器上,自旋锁仅仅当作一个设置内核抢占的开关。如果内核抢占也不存在,那么自旋锁会在编译时被完全剔除出内核。简单的说,
28、自旋锁在内核中主要用来防止多处理器中并发访问临界区,防止内核抢占造成的竞争。另外自旋锁不允许任务睡眠(持有自旋锁的任务睡眠会造成自死锁因为睡眠有可能造成持有锁的内核任务被重新调度,而再次申请自己已持有的锁),它能够在中断上下文中使用。死锁:假设有一个或多个内核任务和一个或多个资源,每个内核都在等待其中的一个资源,但所有的资源都已经被占用了。这便会发生所有内核任务都在相互等待,但它们永远不会释放已经占有的资源,于是任何内核任务都无法获得所需要的资源,无法继续运行,这便意味着死锁发生了。自死琐是说自己占有了某个资源,然后自己又申请自己已占有的资源,显然不可能再获得该资源,因此就自缚手脚了。递归使用
29、一个自旋锁就会出现这种情况。信号量信号量是一种睡眠锁。如果有一个任务试图获得一个已被持有的信号量时,信号量会将其推入等待队列,然后让其睡眠。这时处理器获得自由去执行其它代码。当持有信号量的进程将信号量释放后,在等待队列中的一个任务将被唤醒,从而便可以获得这个信号量。信号量的睡眠特性,使得信号量适用于锁会被长时间持有的情况;只能在进程上下文中使用,因为中断上下文中是不能被调度的;另外当代码持有信号量时,不可以再持有自旋锁。信号量基本使用形式为:static DECLARE_MUTEX(mr_sem);/声明互斥信号量if(down_interruptible(&mr_sem) /可被中断的睡眠,
30、当信号来到,睡眠的任务被唤醒 /临界区 up(&mr_sem); 信号量和自旋锁区别从严格意义上讲,信号量和自旋锁属于不同层次的互斥手段,前者的实现有赖于后者。注意以下原则: 如果代码需要睡眠这往往是发生在和用户空间同步时使用信号量是唯一的选择。由于不受睡眠的限制,使用信号量通常来说更加简单一些。如果需要在自旋锁和信号量中作选择,应该取决于锁被持有的时间长短。理想情况是所有的锁都应该尽可能短的被持有,但是如果锁的持有时间较长的话,使用信号量是更好的选择。另外,信号量不同于自旋锁,它不会关闭内核抢占,所以持有信号量的代码可以被抢占。这意味者信号量不会对影响调度反应时间带来负面影响。自旋锁对信号量
31、需求建议的加锁方法低开销加锁优先使用自旋锁短期锁定优先使用自旋锁长期加锁优先使用信号量中断上下文中加锁使用自旋锁持有锁是需要睡眠、调度使用信号量56、platform总线设备及总线设备如何编写57、kmalloc和vmalloc的区别kmalloc()和vmalloc()介绍kmalloc()用于申请较小的、连续的物理内存1. 以字节为单位进行分配,在中2. void *kmalloc(size_t size, int flags) 分配的内存物理地址上连续,虚拟地址上自然连续3. gfp_mask标志:什么时候使用哪种标志?如下:-情形 相应标志-进程上下文,可以睡眠 GFP_KERNEL进
32、程上下文,不可以睡眠 GFP_ATOMIC中断处理程序 GFP_ATOMIC软中断 GFP_ATOMICTasklet GFP_ATOMIC用于DMA的内存,可以睡眠 GFP_DMA | GFP_KERNEL用于DMA的内存,不可以睡眠 GFP_DMA | GFP_ATOMIC-4. void kfree(const void *ptr)释放由kmalloc()分配出来的内存块vmalloc()用于申请较大的内存空间,虚拟内存是连续的1. 以字节为单位进行分配,在中2. void *vmalloc(unsigned long size) 分配的内存虚拟地址上连续,物理地址不连续3. 一般情况下
33、,只有硬件设备才需要物理地址连续的内存,因为硬件设备往往存在于MMU之外,根本不了解虚拟地址;但为了性能上的考虑,内核中一般使用 kmalloc(),而只有在需要获得大块内存时才使用vmalloc(),例如当模块被动态加载到内核当中时,就把模块装载到由vmalloc()分配 的内存上。4.void vfree(void *addr),这个函数可以睡眠,因此不能从中断上下文调用。malloc(), vmalloc()和kmalloc()区别*kmalloc和vmalloc是分配的是内核的内存,malloc分配的是用户的内存*kmalloc保证分配的内存在物理上是连续的,vmalloc保证的是在虚
34、拟地址空间上的连续,malloc不保证任何东西(这点是自己猜测的,不一定正确)*kmalloc能分配的大小有限,vmalloc和malloc能分配的大小相对较大*内存只有在要被DMA访问的时候才需要物理上连续*vmalloc比kmalloc要慢58、module_init的级别59、添加驱动静态加载和动态加载:静态加载是系统启动的时候由内核自动加载的,这个要事先将驱动编译进内核才行;动态加载,也就是模块加载方式,这种方式下驱动以模块的形式存放在文件系统中,需要时动态载入内核,这种主要用在调试的时候,比较方便灵活。insmod 60、IIC原理,总线框架,设备编写方法,i2c_msg61、ker
35、nel panic62、USB总线,USB传输种类,urb等USB总线:USB总线属于一种轮询式总线,主机控制端口初始化所有的数据传输。每一总线动作最多传送三个数据包,包括令牌(Token)、数据(Data)、联络(HandShake)。按照传输前制定好的原则,在每次传送开始时,主机送一个描述传输动作的种类、方向、USB设备地址和终端号的USB数据包,这个数据包通常被称为令牌包(TokenPacket)。USB设备从解码后的数据包的适当位置取出属于自己的数据。数据传输方向不是从主机到设备就是从设备到主机。在传输开始时,由标志包来标志数据的传输方向,然后发送端开始发送包含信息的数据包或表明没有数
36、据传送。接收端也要相应发送一个握手的数据包表明是否传送成功。发送端和接收端之间的USB数据传输,在主机和设备的端口之间,可视为一个通道。USB中有一个特殊的通道一缺省控制通道,它属于消息通道,设备一启动即存在,从而为设备的设置、状态查询和输入控制信息提供一个入口。USB总线的四种传输类型:1、中断传输:由OUT事务和IN事务构成,用于键盘、鼠标等HID设备的数据传输中 2、批量传输:由OUT事务和IN事务构成,用于大容量数据传输,没有固定的传输速率,也不占用带宽,当总线忙时,USB会优先进行其他类型的数据传输,而暂时停止批量转输。 3、同步传输:由OUT事务和IN事务构成,有两个特别地方,第一
37、,在同步传输的IN和OUT事务中是没有返回包阶段的;第二,在数据包阶段任何的数据包都为DATA0 4、控制传输:最重要的也是最复杂的传输,控制传输由三个阶段构成(初始配置阶段、可选数据阶段、状态信息步骤),每一个阶段能够看成一个的传输,也就是说控制传输其实是由三个传输构成的,用来于USB设备初次加接到主机之后,主机通过控制传输来交换信息,设备地址和读取设备的描述符,使得主机识别设备,并安装相应的驱动程式,这是每一个USB研发者都要关心的问题。URB:USB请求块(USB request block,urb)是USB设备驱动中用来描述与USB设备通信所用的基本载体和核心数据结构,非常类似于网络设
38、备驱动中的sk_buff结构体,是USB主机与设备通信的“电波”。63、同步和互斥同步和互斥相交进程之间的关系主要有两种,同步与互斥。所谓互斥,是指散步在不同进程之间的若干程序片断,当某个进程运行其中一个程序片段时,其它进程就不能运行它们之中的任一程序片段,只能等到该进程运行完这个程序片段后才可以运行。所谓同步,是指散步在不同进程之间的若干程序片断,它们的运行必须严格按照规定的某种先后次序来运行,这种先后次序依赖于要完成的特定的任务。显然,同步是一种更为复杂的互斥,而互斥是一种特殊的同步。也就是说互斥是两个线程之间不可以同时运行,他们会相互排斥,必须等待一个线程运行完毕,另一个才能运行,而同步
39、也是不能同时运行,但他是必须要安照某种次序来运行相应的线程(也是一种互斥)!总结:互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源64、 Linux设备中字符设备与块设备有什么主要的区别?请分别列举一些实际的设备说出它们是属于哪一类设备。答:字符设备:字符设备是个能够像字节流(类似文件)一样被访问的设备,由字符设备驱动程序来
40、实现这种特性。字符设备驱动程序通常至少实现open,close,read和write系统调用。字符终端、串口、鼠标、键盘、摄像头、声卡和显卡等就是典型的字符设备。块设备:和字符设备类似,块设备也是通过/dev目录下的文件系统节点来访问。块设备上能够容纳文件系统,如:u盘,SD卡,磁盘等。 字符设备和块设备的区别仅仅在于内核内部管理数据的方式,也就是内核及驱动程序之间的软件接口,而这些不同对用户来讲是透明的。在内核中,和字符驱动程序相比,块驱动程序具有完全不同的接口65、查看驱动模块中打印信息应该使用什么命令?如何查看内核中已有的字符设备的信息?如何查看正在使用的有哪些中断号?答:1) 查看驱动
41、模块中打印信息的命令:dmesg 2) 查看字符设备信息可以用lsmod 和modprobe,lsmod可以查看模块的依赖关系,modprobe在加载模块时会加载其他依赖的模块。 3)显示当前使用的中断号cat /proc/interrupt66、Linux中引入模块机制有什么好处?答:首先,模块是预先注册自己以便服务于将来的某个请求,然后他的初始化函数就立即结束。换句话说,模块初始化函数的任务就是为以后调用函数预先作准备。好处:1) 应用程序在退出时,可以不管资源的释放或者其他的清除工作,但是模块的退出函数却必须仔细此撤销初始化函数所作的一切。2) 该机制有助于缩短模块的开发周期。即:注册和
42、卸载都很灵活方便。67、copy_to_user()和copy_from_user()主要用于实现什么功能?一般用于file_operations结构的哪些函数里面?答:由于内核空间和用户空间是不能互相访问的,如果需要访问就必须借助内核函数进行数据读写。copy_to_user():完成内核空间到用户空间的复制,copy_from_user():是完成用户空间到内核空间的复制。一般用于file_operations结构里的read,write,ioctl等内存数据交换作用的函数。当然,如果ioctl没有用到内存数据复制,那么就不会用到这两个函数。68、请简述主设备号和次设备号的用途。如果执行m
43、knod chartest c 4 64,创建chartest设备。请分析chartest使用的是那一类设备驱动程序。答:1)主设备号:主设备号标识设备对应的驱动程序。虽然现代的linux内核允许多个驱动程序共享主设备号,但我们看待的大多数设备仍然按照“一个主设备对应一个驱动程序”的原则组织。 次设备号:次设备号由内核使用,用于正确确定设备文件所指的设备。依赖于驱动程序的编写方式,我们可以通过次设备号获得一个指向内核设备的直接指针,也可将此设备号当作设备本地数组的索引。2)chartest 由驱动程序4管理,该文件所指的设备是64号设备。(感觉类似于串口终端或者字符设备终端)。69、设备驱动程
44、序中如何注册一个字符设备?分别解释一下它的几个参数的含义。答:注册一个字符设备驱动有两种方法:1) void cdev_init(struct cdev *cdev, struct file_operations *fops)该注册函数可以将cdev结构嵌入到自己的设备特定的结构中。cdev是一个指向结构体cdev的指针,而fops是指向一个类似于file_operations结构(可以是file_operations结构,但不限于该结构)的指针.2) int register_chrdev(unsigned int major, const char *namem , struct file
45、)operations *fopen);该注册函数是早期的注册函数,major是设备的主设备号,name是驱动程序的名称,而fops是默认的file_operations结构(这是只限于file_operations结构)。对于register_chrdev的调用将为给定的主设备号注册0255作为次设备号,并为每个设备建立一个对应的默认cdev结构。70、请简述中断与DMA的区别。Linux设备驱动程序中,使用哪个函数注册和注销中断处理程序?答:1)DMA:是一种无须CPU的参与就可以让外设与系统内存之间进行双向数据传输的硬件机制,使用DMA可以使系统CPU从实际的IO数据传输过程中摆脱出来,从而大大提高系统的吞吐率。中断:是指CPU在执行程序的过程中,出现了某些突发事件时CPU必须暂停执行当前的程序,转去处理突发事件,处理完毕后CPU又返回源程序被中断的位置并继续执行。所以中断和MDA的区别就是MDA不需CPU参与而中断是需要CPU参与的。2)中断注册函数和中断注销函数注册中断:int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs
限制150内