Linux驱动⾯试总结
前⾔: 这篇⽂章主要是对linux驱动⾯试题⼀个整理跟总结,参考了很多⽹上的资料,基本涵盖linux驱动相关⾯试内容。我把他们⼤概的分为三部分:基础部分,同步相关,还有中断部分。中断,同步相关基本都是必问的。下⾯也会对这⼏个⽅⾯的⾯试题进⾏详细的解答,你把下⾯的⾯试题弄懂了,应该可以应付⼤部分linux驱动⾯试了。要想真正的理解,还的在实践中多动⼿调试多总结,如果有什么地⽅错了或者不全,欢迎⼩伙伴们留⾔。
⼀. 基础题:
物业保洁员管理制度1. linux中内核空间及⽤户空间的区别?⽤户空间与内核通信⽅式有哪些?
2. 字符设备和块设备的区别,请分别列举⼀些实际的设备说出它们是属于哪⼀类设备
字符设备:字符设备是个能够像字节流(类似⽂件)⼀样被访问的设备,由字符设备驱动程序来实现这种特性。字符设备驱动程序通常⾄少实现open,close,read和write系统调⽤。字符终端、串⼝、⿏标、键盘、摄像头、声卡和显卡等就是典型的字符设备。
块设备:和字符设备类似,块设备也是通过/dev⽬录下的⽂件系统节点来访问。块设备上能够容纳⽂件系统,如:u盘,SD卡,磁盘等。
字符设备和块设备的区别仅仅在于内核内部管理数据的⽅式,也就是内核及驱动程序之间的软件接⼝,⽽这些不同对⽤户来讲是透明的。在内核中,和字符驱动程序相⽐,块驱动程序具有完全不同的接⼝。继承者们大结局
3. linux内核的启动过程(源代码级)?
4. linux中系统调⽤过程?如:应⽤程序中read()在linux中执⾏过程即从⽤户空间到内核空间?
5. linux调度原理?
6. 查看驱动模块中打印信息应该使⽤什么命令?如何查看内核中已有的字符设备的信息?如何查看正在使⽤的有哪些中断号?
1) 查看驱动模块中打印信息的命令:dmesg
2) 查看字符设备信息可以⽤lsmod 和modprobe,lsmod可以查看模块的依赖关系,modprobe在加载模块时会加载其他依赖的 模块。
3) 显⽰当前使⽤的中断号cat /proc/interrupt
7. copy_to_user()和copy_from_user()主要⽤于实现什么功能?⼀般⽤于file_operations结构的哪些函数⾥⾯?
由于内核空间和⽤户空间是不能互相访问的,如果需要访问就必须借助内核函数进⾏数据读写。copy_to_user():完成内核空间到⽤户空间的复制,copy_from_user():是完成⽤户空间到内核空间的复制。⼀般⽤于file_operations结构⾥的read,write,ioctl等内存数据交换作⽤的函数。当然,如果ioctl没有⽤到内存数据复制,那么就不会⽤到这两个函数。
台湾旅游必去十大景点8. 请简述主设备号和次设备号的⽤途。如果执⾏mknod chartest c 4 64,创建chartest设备。请分析chartest使⽤的是那⼀类设备驱动程序。
1)主设备号:主设备号标识设备对应的驱动程序。虽然现代的linux内核允许多个驱动程序共享主设备号,但我们看待的⼤多数设备仍然按照“⼀个主设备对应⼀个驱动程序”的原则组织。
次设备号:次设备号由内核使⽤,⽤于正确确定设备⽂件所指的设备。依赖于驱动程序的编写⽅式,我们可以通过次设备号获得⼀个指向内核设备的直接指针,也可将此设备号当作设备本地数组的索引。
2)chartest 表⽰设备节点,4表⽰主设备号,64表⽰次设备号。(感觉类似于串⼝终端或者字符设备终端)。
9. 设备驱动程序中如何注册⼀个字符设备?分别解释⼀下它的⼏个参数的含义。
注册⼀个字符设备驱动有两种⽅法:
如何用照片做抖音视频1) void cdev_init(struct cdev *cdev, struct file_operations *fops)
该注册函数可以将cdev结构嵌⼊到⾃⼰的设备特定的结构中。cdev是⼀个指向结构体cdev的指针,⽽fops是指向⼀个类似于f
file_operations结构(可以是file_operations结构,但不限于该结构)的指针.
2) int register_chrdev(unsigned int major, const char *namem , struct file)operations *fopen);
该注册函数是早期的注册函数,major是设备的主设备号,name是驱动程序的名称,⽽fops是默认的file_operations结构(这 是只限于file_operations结构)。对于register_chrdev的调⽤将为给定的主设备号注册0-255作为次设备号,并为每个 设备建 ⽴⼀个对应的默认cdev结构。
10. linux中RCU原理?
11. linux内存如何划分以及如何使⽤?虚拟地址及物理地址的概念以及转换,⾼端内存的概念?
12. 字符型驱动设备怎么创建设备⽂件?
⼿动创建:mknod /dev/led c 250 0 其中dev/led 为设备节点 c 代表字符设备 250代表主设备号 0代表次设备号
还有UDEV/MDEV⾃动创建设备⽂件的⽅式,UDEV/MDEV是运⾏在⽤户态的程序,可以动态管理设备⽂件,包括创建和删除设备⽂件,运⾏在⽤户态意味着系统要运⾏之后。在 /etc/init.d/rcS 脚本⽂件中会执⾏ mdev -s ⾃动创建设备节点。
13. insmod ⼀个驱动模块,会执⾏模块中的哪个函数?rmmod呢?这两个函数在设计上要注意哪些?遇到过卸载驱动出现异常没?是什么问题引起的?
答: insmod调⽤init函数,rmmod调⽤exit函数。这两个函数在设计时要注意什么?卸载模块时曾出现卸载失败的情形,原因是存在进程正在使⽤模块,检查代码后发现产⽣了死锁的问题。
要注意在init函数中申请的资源在exit函数中要释放,包括存储,ioremap,定时器,⼯作队列等等。也就是⼀个模块注册进内核,退出内核时要清理所带来的影响,带⾛⼀切不留下⼀点痕迹。
14. 设备驱动模型三个重要成员是?platform总线的匹配规则是?在具体应⽤上要不要先注册驱动再注册设备?有先后顺序没?
设备驱动模型三个重要成员是 总线、设备、驱动;
platfoem总线的匹配规则是:要匹配的设备和驱动都要注册,设备可以在设备树⾥注册,也可以通过代码注册设备,匹配成功会去调⽤驱动程序⾥的probe函数(probe函数在这个platform_driver结构体中注册)。
15. 内核函数mmap的实现原理,机制?
16. 在驱动调试过程中遇到过oops没?你是怎么处理的?
17. ioctl和unlock_ioctl有什么区别?
18. 驱动中操作物理绝对地址为什么要先ioremap?
因为内核没有办法直接访问物理内存地址,必须先通过ioremap获得对应的虚拟地址
19. 你平常是怎么⽤C写嵌⼊式系统的死循环的?
for(;;){}
while(1){}
⼀般for(;;)性能更优
for(;;){}
这两个;; 空语句,编译器⼀般会优掉的,直接进⼊死循环
while(1){}
每循环⼀次都要判断常量1是不是等于零,在这⾥while⽐for多做了这点事
不过从汇编的⾓度来说,都是⼀样的代码。
20. 列举最少3种你所知道的嵌⼊式的体系结构,并请说明什么是ARM体系结构。
arm,mips,x86
21. kmalloc和vmalloc的区别
22. IIC原理,总线框架,设备编写⽅法,i2c_msg
23. kernel panic
24. Linux中的⽤户模式和内核模式是什么含意?
25. 怎样申请⼤块内核内存?
vmalloc
26. ⽤户进程间通信主要哪⼏种⽅式?
27.linux编译时⽤到的参数含义及?
28. 内核配置编译及Makefile?
29.谈谈对Volatile关键字的理解?
30. framebuffer机制?
Linux抽象出FrameBuffer这个设备来供⽤户态进程实现直接写屏。Framebuffer机制模仿显卡的功能,将显卡硬件结构抽象掉,可以通过Framebuffer的读写直接对显存进⾏操作。⽤户可以将Framebuffer看成是显⽰内存的⼀个映像,通过mmap将其映射到进程地址空间之后,就可以直接进⾏读写操作,⽽写操作可以⽴即反应在屏幕上。这种操作是抽象的,统⼀的。⽤户不必关⼼物理显存的位置、换页
机制等等具体细节,这些都是由Framebuffer设备驱动来完成的。通过mmap调⽤把显卡的物理内存空间映射到⽤户空间
⼆. 同步相关:
1. spinlock与信号量的区别?
2. linux中的同步机制?
3. linux系统实现原⼦操作有哪些⽅法?
4. ⾃旋锁和信号量在互斥使⽤时需要注意哪些?在中断服务程序⾥⾯的互斥是使⽤⾃旋锁还是信号量?还是两者都能⽤?为什么(答案见1分析)?
答:使⽤⾃旋锁的进程不能睡眠,使⽤执⾏时间短的任务,使⽤信号量的进程可以睡眠,适合于执⾏时间较长的任务。中断服务例程中的互斥使⽤的是⾃旋锁,原因是在中断处理例程中,硬中断是关闭的,这样会丢失可能到来的中断。
5. 驱动⾥⾯为什么要有并发、互斥的控制?如何实现?讲个例⼦?
并发(concurrency)指的是多个执⾏单元同时、并⾏被执⾏,⽽并发的执⾏单元对共 享资源(硬件资源和软件上的全局变量、静态变量等)的访问则很容易导致竞态(race conditions)。
解决竞态问题的途径是保证对共享资源的互斥访问,所谓互斥访问就是指⼀个执⾏单元 在访问共享资源的时候,其他的执⾏单元都被禁⽌访问。
访问共享资源的代码区域被称为临界区,临界区需要以某种互斥机 制加以保护,中断屏蔽,原⼦操作,⾃旋锁,和信号量都是linux设备驱动中可采⽤的互斥途径。
三. 中断相关:
1. linux中软中断的实现原理?
2. linux中断响应的执⾏流程
3. linux中断实现机制、tasklet和workqueue的区别和底层实现的区别,为什么要区分中断上半部和中断下半部。
tasklet和workqueue区别?
tasklet运⾏于中断上下⽂,不允许阻塞 、休眠,⽽workqueue运⾏与进程上下⽂,可以休眠和阻塞。
为什么要区分上半部和下半部?
中断服务程序异步执⾏,可能会中断其他的重要代码,包括其他中断服务程序。因此,为了避免被中断的代码延迟太长的时间,中断服务程序需要尽快运⾏,⽽且执⾏的时间越短越好,所以中断程序只作必须的⼯作,其他⼯作推迟到以后处理。所以Linux把中断处理切为两个部分:上半部和下半部。上半部就是中断处理程序,它需要完成的⼯作越少越好,执⾏得越快越好,⼀旦接收到⼀个中断,它就⽴即开始执⾏。像对时间敏感、与硬件相关、要求保证不被其他中断打断的任务往往放在中断处理程序中执⾏;⽽剩下的与中断有相关性但是可以延后的任务,如对数据的操作处理,则推迟⼀点由下半部完成。下半部分延后执⾏且执⾏期间可以相应所有中断,这样可使系统处于中断屏蔽状态的时间尽可能的短,提⾼了系统的响应能⼒。实现了程序运⾏快同时完成的⼯作量多的⽬标。
4. 中断的申请及何时执⾏(何时执⾏中断处理函数)?
中断的响应流程:cpu接受中断->保存中断上下⽂跳转到中断处理历程->执⾏中断上半部->执⾏中断下半部->恢复中断上下⽂。
中断的申请request_irq的正确位置:应该是在第⼀次打开 、硬件被告知终端之前。
5. 中断注册函数和中断注销函数
6. 中断和轮询哪个效率⾼?怎样决定是采⽤中断⽅式还是采⽤轮询⽅式去实现驱动?
中断是CPU处于被动状态下来接受设备的信号,⽽轮询是CPU主动去查询该设备是否有请求。凡事都是两⾯性,所以,看效率不能简单的说那个效率⾼。如果是请求设备是⼀个频繁请求cpu的设备,或者有⼤量数据请求的⽹络设备,那么轮询的效率是⽐中断⾼。如果是⼀般设备,并且该设备请求cpu的频率⽐较底,则⽤中断效率要⾼⼀些。主要是看请求频率。
7. 写⼀个中断服务需要注意哪些?如果中断产⽣之后要做⽐较多的事情你是怎么做的?
杨梅怎么清洗才能洗得干净第⼀: 中断处理例程应该尽量短,把能放在后半段(tasklet,等待队列等)的任务尽量放在后半段。
写⼀个中断服务程序要注意快进快出,在中断服务程序⾥⾯尽量快速采集信息,包括硬件信息,然后退出中断,要做其它事情可以使⽤⼯作队列或者tasklet⽅式。也就是中断上半部和下半部。
第⼆:中断服务程序中不能有阻塞操作。应为中断期间是完全占⽤CPU的(即不存在内核调度),中断被阻塞住,其他进程将⽆法操作;
燕云台 电视剧第三:中断服务程序注意返回值,要⽤操作系统定义的宏做为返回值,⽽不是⾃⼰定义的OK,FAIL之类的。
8. 驱动中操作物理绝对地址为什么要先ioremap?
因为内核没有办法直接访问物理内存地址,必须先通过ioremap获得对应的虚拟地址。
9. IRQ和FIQ有什么区别,在CPU⾥⾯是是怎么做的?
10. Linux软中断和⼯作队列的作⽤是什么?
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论