面试--驱动

来源:互联网 发布:脑死亡知乎 编辑:程序博客网 时间:2024/06/06 09:40
1.为什么开始时一直必须用汇编代码;
答:后面很多功能是需要main函数实现,但是main函数需要栈,只能由汇编实现
并且刚开始要进入svc模式,只有汇编能实现

1.为什么开始要设置成SVC模式
答:SVC模式能最大限度访问资源,而且内核模式必须要求是SVC

2.为什么要关闭MMU,数据预取,以及缓存
关闭数据预取:内核里面有些变量是volatile型的,如果过早预取进cathe,而volatile在运行时又转变了会影响最终运行。
关闭MMU:刚开始时是没有系统的,那么就不需要访问虚拟地址,从而不需要内存映射

2.DMA(直接内存访问)跟中断的区别
答:DMA是不需要CPU的,而中断需要

3.r0-r2传递给内核的参数
答:r0:0              
r1:板子的ID    r2:uboot传递给内核的参数的起始地址

4.私有,公共中断的区别
答:私有中断只有由特定的CPU处理,公共的不限cpu

1、什么是僵尸进程?

答:僵尸进程就是已经撤销但仍然占着资源的进程。

为什么会产生僵尸进程?

如果子进程结束之后,父进程继续运行但没有调用wait/waitpid,子进程将会变成僵尸进程。僵尸进程的存在是因为子进程认为父进程会需要子进程的信息。

如何清理僵尸进程?

答:在main函数内部给SIGCHLD注册一个信号处理函数handler;定义信号处理函数void handler(waitpid(-1,NULL, WNOHANG)> 0), 调用waitpid处理僵尸进程。


2、什么是系统调用?

答:系统调用是用户进程和内核交互的接口。


3、顺序表和链表的优缺点?

答:顺序表访问方便,时间效率快,但插入删除不变,浪费空间;链表动态申请灵活,需要的时候才开辟很小的一部分内存,但是遍历起来较慢。


4、时间复杂度是什么?

答:时间复杂度是一个函数,定量描述了算法的运行时间;一个算法中语句的执行次数称为语句频度或时间频度,语句执行次数越多,话费的时间越多。


5、有名管道和无名管道有什么区别?(管道就是一种通信方式,是一个程序的输出直接连接到另一个程序的输入)

答:无名管道只能用于有亲缘关系的进程,无名管道是半双工的通信模式,有固定的读端和写段=端,数据只能像一个方向流动,需要双方通信时就要建立两个管道;(当管道中无数据时,读操作会阻塞;如果读进程不读走管道缓冲区的数据,那么写操作将会一直阻塞。)有名管道可以实现两个互不相关的程序之间的通信,可以通过路径名来指出,有名管道是全双工的通信模式,遵循先进先出的原则。(无名管道和有名管道都不支持lseek()操作)。


6、信号和信号量的区别?

答:信号可以直接进行用户进程和内核进程之间的交互;

信号量相当于信号灯,程序中是一个非负整数,表示状态。其中P操作是表示分配资源,V操作表示释放资源。


1、 Linux设备中字符设备与块设备有什么主要的区别?请分别列举一些实际的设备说出它们是属于哪一类设备。

    字符设备:字符设备是个能够像字节流(类似文件)一样被访问的设备,由字符设备驱动程序来实现这种特性。字符设备驱动程序通常至少实现open,close,read和write系统调用。字符终端、串口、鼠标、键盘、摄像头、声卡和显卡等就是典型的字符设备。

    块设备:和字符设备类似,块设备也是通过/dev目录下的文件系统节点来访问。块设备上能够容纳文件系统,如:u盘,SD卡,磁盘等。

    字符设备和块设备的区别仅仅在于内核内部管理数据的方式,也就是内核及驱动程序之间的软件接口,而这些不同对用户来讲是透明的。在内核中,和字符驱动程序相比,块驱动程序具有完全不同的接口。

3、Linux中引入模块机制有什么好处?

       首先,模块是预先注册自己以便服务于将来的某个请求,然后他的初始化函数就立即结束。换句话说,模块初始化函数的任务就是为以后调用函数预先作准备

好处:

1) 应用程序在退出时,可以不管资源的释放或者其他的清除工作,但是模块的退出函数却必须仔细此撤销初始化函数所作的一切。

2) 该机制有助于缩短模块的开发周期。即:注册和卸载都很灵活方便

5、请简述主设备号和次设备号的用途。如果执行mknod chartest c 4 64,创建chartest设备。请分析chartest使用的是那一类设备驱动程序。

1)主设备号:主设备号标识设备对应的驱动程序。虽然现代的linux内核允许多个驱动程序共享主设备号,但我们看待的大多数设备仍然按照“一个主设备对应一个驱动程序”的原则组织。

   次设备号:次设备号由内核使用,用于正确确定设备文件所指的设备。依赖于驱动程序的编写方式,我们可以通过次设备号获得一个指向内核设备的直接指针,也可将此设备号当作设备本地数组的索引。

2)chartest 由驱动程序4管理,该文件所指的设备是64号设备。(感觉类似于串口终端或者字符设备终端)。


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

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


11、简单描述skbuff这个数据结构在网络结构中所起到的作用,为什么需要一个skbuff,它的分配和释放主要都在什么部位

        sk_buff结构非常重要,它的含义为“套接字缓冲区”,用于在linux网络子系统中的盖层之间传递数据。

当发送数据包时,linux内核的网络处理模块必须建立一个包含要传输的数据包的sk_buff,然后将sk_buff递交给下层,各层在sk_buff中添加不同的协议头直至交给网络设备发送。同样的,当网络设备从网络媒介上接受到数据包后,它必须将接受到的数据转换为sk_buff数据结构并传递给上层,盖层不抛去相应的协议头直至交给用户。分配sk_buff在接受一开始就应该分配,在发送完毕数据之后可以释放sk_buff


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

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

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

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

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


14、自旋锁和信号量在互斥使用时需要注意哪些?在中断服务程序里面的互斥是使用自旋锁还是信号量?还是两者都能用?为什么?

      使用自旋锁的进程不能睡眠,使用信号量的进程可以睡眠

      中断服务例程中的互斥使用的是自旋锁,原因是在中断处理例程中,硬中断是关闭的;但是要注意这样会丢失可能到来的中断。


16、insmod 一个驱动模块,会执行模块中的哪个函数?rmmod呢?这两个函数在设计上要注意哪些?遇到过卸载驱动出现异常没?是什么问题引起的?

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

      要注意在init函数中申请的资源在exit函数中要释放,包括存储,ioremap,定时器,工作队列等等。也就是一个模块注册进内核,退出内核时要清理所带来的影响,带走一切不留下一点痕迹。


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

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



【tasklet 和定期器的区别】

1. 执行时间

定时器的执行:时间是确定的
tasklet       :不确定的


26、信号量简介

        这里也介绍下信号量的概念,因为它的用法和自旋锁有相似的地方。

       Linux中的信号量是一种睡眠锁。如果有一个任务试图获得一个已被持有的信号量时,信号量会将其推入等待队列,然后让其睡眠。这时处理器获得自由去执行其它代码。当持有信号量的进程将信号量释放后,在等待队列中的一个任务将被唤醒,从而便可以获得这个信号量。



29、在Linux C中,ls这个命令是怎么被执行的?

        使用fork创建一个进程或exec函数族覆

0 0
原创粉丝点击