linux驱动面试题2018(面试题整理,含答案)

吃可爱长大的小学妹 提交于 2019-12-23 21:47:37

linux驱动面试题2018(面试题整理,含答案)

  前言: 这篇文章主要是对linux驱动面试题一个整理跟总结,参考了很多网上的资料,基本涵盖linux驱动相关面试内容。我把他们大概的分为三部分:基础部分,同步相关,还有中断部分。中断,同步相关基本都是必问的。下面也会对这几个方面的面试题进行详细的解答,你把下面的面试题弄懂了,应该可以应付大部分linux驱动面试了。要想真正的理解,还的在实践中多动手调试多总结,如果有什么地方错了或者不全,欢迎小伙伴们留言。

一. 基础题:

  1. linux中内核空间及用户空间的区别?用户空间与内核通信方式有哪些?

    https://blog.csdn.net/bingqingsuimeng/article/details/7924756

  2. 字符设备和块设备的区别,请分别列举一些实际的设备说出它们是属于哪一类设备

        字符设备:字符设备是个能够像字节流(类似文件)一样被访问的设备,由字符设备驱动程序来实现这种特性。字符设备驱动程序通常至少实现open,close,read和write系统调用。字符终端、串口、鼠标、键盘、摄像头、声卡和显卡等就是典型的字符设备。
    
       块设备:和字符设备类似,块设备也是通过/dev目录下的文件系统节点来访问。块设备上能够容纳文件系统,如:u盘,SD卡,磁盘等。
    
       字符设备和块设备的区别仅仅在于内核内部管理数据的方式,也就是内核及驱动程序之间的软件接口,而这些不同对用户来讲是透明的。在内核中,和字符驱动程序相比,块驱动程序具有完全不同的接口。
    
  3. linux内核的启动过程(源代码级)?

    https://www.cnblogs.com/CrazyCatJack/p/6135435.html

  4. linux中系统调用过程?如:应用程序中read()在linux中执行过程即从用户空间到内核空间?

    https://blog.csdn.net/kai_zone/article/details/80459334

    https://my.oschina.net/haomcu/blog/468656

  5. linux调度原理?

    https://blog.csdn.net/janneoevans/article/details/8125106

  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表示次设备号。(感觉类似于串口终端或者字符设备终端)。

  1. 设备驱动程序中如何注册一个字符设备?分别解释一下它的几个参数的含义。

    注册一个字符设备驱动有两种方法:

    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结构。
    
  2. linux中RCU原理?

    https://www.cnblogs.com/-wang-cheng/p/5401653.html

  3. linux内存如何划分以及如何使用?虚拟地址及物理地址的概念以及转换,高端内存的概念?

    https://www.cnblogs.com/dongzhiquan/p/5621906.html

    https://www.cnblogs.com/wuchanming/p/4360277.html

  4. 字符型驱动设备怎么创建设备文件?

       手动创建:mknod /dev/led c 250 0    其中dev/led 为设备节点 c 代表字符设备 250代表主设备号 0代表次设备号
    
        还有UDEV/MDEV自动创建设备文件的方式,UDEV/MDEV是运行在用户态的程序,可以动态管理设备文件,包括创建和删除设备文件,运行在用户态意味着系统要运行之后。在  /etc/init.d/rcS 脚本文件中会执行 mdev -s 自动创建设备节点。
    
  5. insmod 一个驱动模块,会执行模块中的哪个函数?rmmod呢?这两个函数在设计上要注意哪些?遇到过卸载驱动出现异常没?是什么问题引起的?

    答: insmod调用init函数,rmmod调用exit函数。这两个函数在设计时要注意什么?卸载模块时曾出现卸载失败的情形,原因是存在进程正在使用模块,检查代码后发现产生了死锁的问题。

       要注意在init函数中申请的资源在exit函数中要释放,包括存储,ioremap,定时器,工作队列等等。也就是一个模块注册进内核,退出内核时要清理所带来的影响,带走一切不留下一点痕迹。
    
  6. 设备驱动模型三个重要成员是?platform总线的匹配规则是?在具体应用上要不要先注册驱动再注册设备?有先后顺序没?

        设备驱动模型三个重要成员是 总线、设备、驱动;
    
        platfoem总线的匹配规则是:要匹配的设备和驱动都要注册,设备可以在设备树里注册,也可以通过代码注册设备,匹配成功会去调用驱动程序里的probe函数(probe函数在这个platform_driver结构体中注册)。
    
  7. 内核函数mmap的实现原理,机制?

    https://blog.csdn.net/yinjiabin/article/details/7575653

    https://blog.csdn.net/edwardlulinux/article/details/8604400

  8. 在驱动调试过程中遇到过oops没?你是怎么处理的?

    https://blog.csdn.net/kangear/article/details/8217329

  9. ioctl和unlock_ioctl有什么区别?

    https://blog.csdn.net/zhuangtim1987/article/details/41963411

    https://blog.csdn.net/cbl709/article/details/7295772

  10. 驱动中操作物理绝对地址为什么要先ioremap?

       因为内核没有办法直接访问物理内存地址,必须先通过ioremap获得对应的虚拟地址
    
       https://blog.csdn.net/zqixiao_09/article/details/50859505
    
  11. 你平常是怎么用C写嵌入式系统的死循环的?

    for(;😉{}

    while(1){}

    一般for(;;)性能更优

    for(;😉{} 这两个;; 空语句,编译器一般会优掉的,直接进入死循环

    while(1){} 每循环一次都要判断常量1是不是等于零,在这里while比for多做了这点事

    不过从汇编的角度来说,都是一样的代码。

  12. 列举最少3种你所知道的嵌入式的体系结构,并请说明什么是ARM体系结构。

    arm,mips,x86

    https://blog.csdn.net/qq_32651225/article/details/78176567

    https://blog.csdn.net/chengtong222/article/details/64440661

  13. kmalloc和vmalloc的区别

    https://www.cnblogs.com/hongzhunzhun/p/4533960.html

    https://www.cnblogs.com/wuchanming/p/4465155.html

  14. IIC原理,总线框架,设备编写方法,i2c_msg

    https://blog.csdn.net/kai_zone/article/details/78026931

    https://blog.csdn.net/kai_zone/article/details/78029501

  15. kernel panic

    https://www.cnblogs.com/cherishui/p/3881428.html

  16. Linux中的用户模式和内核模式是什么含意?

    https://blog.csdn.net/sinat_15799399/article/details/44238893

  17. 怎样申请大块内核内存?

    vmalloc

  18. 用户进程间通信主要哪几种方式?

    https://blog.csdn.net/wh_sjc/article/details/70283843

27.linux编译时用到的参数含义及?

https://blog.csdn.net/taoyanqi8932/article/details/51758722
  1. 内核配置编译及Makefile?

    https://www.cnblogs.com/CrazyCatJack/p/6121231.html

29.谈谈对Volatile关键字的理解?

https://blog.csdn.net/kai_zone/article/details/77965302

  1. framebuffer机制?

    Linux抽象出FrameBuffer这个设备来供用户态进程实现直接写屏。Framebuffer机制模仿显卡的功能,将显卡硬件结构抽象掉,可以通过Framebuffer的读写直接对显存进行操作。用户可以将Framebuffer看成是显示内存的一个映像,通过mmap将其映射到进程地址空间之后,就可以直接进行读写操作,而写操作可以立即反应在屏幕上。这种操作是抽象的,统一的。用户不必关心物理显存的位置、换页机制等等具体细节,这些都是由Framebuffer设备驱动来完成的。通过mmap调用把显卡的物理内存空间映射到用户空间

二. 同步相关:

  1. spinlock与信号量的区别?

    https://blog.csdn.net/xiaohuima_dong/article/details/46423793

    https://www.cnblogs.com/tureno/articles/6067441.html

  2. linux中的同步机制?

    https://blog.csdn.net/waltonhuang/article/details/52212762

    https://blog.csdn.net/tong646591/article/details/8484596

  3. linux系统实现原子操作有哪些方法?

https://www.cnblogs.com/fanzhidongyzby/p/3654855.html

https://blog.csdn.net/vividonly/article/details/6599502

  1. 自旋锁和信号量在互斥使用时需要注意哪些?在中断服务程序里面的互斥是使用自旋锁还是信号量?还是两者都能用?为什么(答案见1分析)?

    答:使用自旋锁的进程不能睡眠,使用执行时间短的任务,使用信号量的进程可以睡眠,适合于执行时间较长的任务。中断服务例程中的互斥使用的是自旋锁,原因是在中断处理例程中,硬中断是关闭的,这样会丢失可能到来的中断。

  2. 驱动里面为什么要有并发、互斥的控制?如何实现?讲个例子?

    并发(concurrency)指的是多个执行单元同时、并行被执行,而并发的执行单元对共 享资源(硬件资源和软件上的全局变量、静态变量等)的访问则很容易导致竞态(race conditions)。

       解决竞态问题的途径是保证对共享资源的互斥访问,所谓互斥访问就是指一个执行单元 在访问共享资源的时候,其他的执行单元都被禁止访问。
    
        访问共享资源的代码区域被称为临界区,临界区需要以某种互斥机 制加以保护,中断屏蔽,原子操作,自旋锁,和信号量都是linux设备驱动中可采用的互斥途径。
    

三. 中断相关:

可以先看一下五篇系列文章:https://blog.csdn.net/droidphone/article/category/1118447

   这篇我收藏的文档详细的叙述了中断上半部及下半部的原理及注意点,如果对其不理解可以下载下来看看,由于CSDN最低没有0积分,那就最低的一个积分吧。下载地址:https://download.csdn.net/download/kai_zone/10631972
  1. linux中软中断的实现原理?

    https://blog.csdn.net/DroidPhone/article/details/7518428

    https://www.linuxidc.com/Linux/2014-03/98013.htm

  2. linux中断响应的执行流程

    https://blog.csdn.net/yimu13/article/details/6803957

  3. linux中断实现机制、tasklet和workqueue的区别和底层实现的区别,为什么要区分中断上半部和中断下半部。

(中断上半部及下半部详细文档:https://download.csdn.net/download/kai_zone/10631972)

tasklet和workqueue区别?
tasklet运行于中断上下文,不允许阻塞 、休眠,而workqueue运行与进程上下文,可以休眠和阻塞。
为什么要区分上半部和下半部?
中断服务程序异步执行,可能会中断其他的重要代码,包括其他中断服务程序。因此,为了避免被中断的代码延迟太长的时间,中断服务程序需要尽快运行,而且执行的时间越短越好,所以中断程序只作必须的工作,其他工作推迟到以后处理。所以Linux把中断处理切为两个部分:上半部和下半部。上半部就是中断处理程序,它需要完成的工作越少越好,执行得越快越好,一旦接收到一个中断,它就立即开始执行。像对时间敏感、与硬件相关、要求保证不被其他中断打断的任务往往放在中断处理程序中执行;而剩下的与中断有相关性但是可以延后的任务,如对数据的操作处理,则推迟一点由下半部完成。下半部分延后执行且执行期间可以相应所有中断,这样可使系统处于中断屏蔽状态的时间尽可能的短,提高了系统的响应能力。实现了程序运行快同时完成的工作量多的目标。

  1. 中断的申请及何时执行(何时执行中断处理函数)?

    中断的响应流程:cpu接受中断->保存中断上下文跳转到中断处理历程->执行中断上半部->执行中断下半部->恢复中断上下文。
    中断的申请request_irq的正确位置:应该是在第一次打开 、硬件被告知终端之前。

  2. 中断注册函数和中断注销函数

    https://www.cnblogs.com/lifexy/p/7506613.html

  3. 中断和轮询哪个效率高?怎样决定是采用中断方式还是采用轮询方式去实现驱动?

    中断是CPU处于被动状态下来接受设备的信号,而轮询是CPU主动去查询该设备是否有请求。凡事都是两面性,所以,看效率不能简单的说那个效率高。如果是请求设备是一个频繁请求cpu的设备,或者有大量数据请求的网络设备,那么轮询的效率是比中断高。如果是一般设备,并且该设备请求cpu的频率比较底,则用中断效率要高一些。主要是看请求频率。

  4. 写一个中断服务需要注意哪些?如果中断产生之后要做比较多的事情你是怎么做的?

    第一: 中断处理例程应该尽量短,把能放在后半段(tasklet,等待队列等)的任务尽量放在后半段。

    写一个中断服务程序要注意快进快出,在中断服务程序里面尽量快速采集信息,包括硬件信息,然后退出中断,要做其它事情可以使用工作队列或者tasklet方式。也就是中断上半部和下半部。

    第二:中断服务程序中不能有阻塞操作。应为中断期间是完全占用CPU的(即不存在内核调度),中断被阻塞住,其他进程将无法操作;

    第三:中断服务程序注意返回值,要用操作系统定义的宏做为返回值,而不是自己定义的OK,FAIL之类的。

  5. 驱动中操作物理绝对地址为什么要先ioremap?

    因为内核没有办法直接访问物理内存地址,必须先通过ioremap获得对应的虚拟地址。

  6. IRQ和FIQ有什么区别,在CPU里面是是怎么做的?

    https://blog.csdn.net/u011308691/article/details/46476985

  7. Linux软中断和工作队列的作用是什么?

    https://blog.csdn.net/godleading/article/details/52971179

参考文章:http://www.mamicode.com/info-detail-2283409.html

https://blog.csdn.net/suiyuan19840208/article/details/20392151

https://blog.csdn.net/zqixiao_09/article/details/50937907

https://blog.csdn.net/lhhero701/article/details/51171948
————————————————
版权声明:本文为CSDN博主「墨尘深巷」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/kai_zone/article/details/82021233

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!