嵌软秋招两万字八股文汇总(六)

面试问题:

Cvte面试:

1、 介绍一下Linux内核的链表。

采用侵入式设计,list_head结构体,不包含数据,只包含指向前一个结构体的指针prev和后一个的next;用的时候首先用LIST_HEAD创建一个空的链表头,是由linux内核提供通用的链表操作宏和函数进行链表操作,避免了操作函数的代码重复,实现通用性,提高了效率。

海康面试:

2、 linux驱动开发里中断嵌套可能会发生什么问题?

上半部/下半部冲突:如果中断嵌套发生在相同设备的中断线上,并且新的中断触发了与当前正在执行的上半部或下半部相同的处理逻辑,可能会导致数据竞争、状态不一致或其他未定义的行为。 例如,两个中断可能会同时尝试修改同一个硬件寄存器。

自旋锁死锁;在中断上下文中只能使用自旋锁,并且要注意避免死锁。 考虑使用 spin_lock_irqsave() 和 spin_unlock_irqrestore() 来在获取锁之前禁用中断,并在释放锁之后恢复中断状态。

内核栈溢出;Linux 内核为每个 CPU 维护一个内核栈,中断上下文使用这个内核栈。如果中断嵌套的层数过多,或者 ISR 使用了大量的栈空间,就可能导致内核栈溢出。

3、 在驱动开发中遇到最大的问题是什么?

4、 什么是上下半部?

上半部 (Top Half):

也称为中断服务例程 (ISR)。

在中断发生时立即执行,由硬件中断直接触发。

运行在中断上下文中,这意味着:

不能睡眠 (sleep)。

优先级高于所有进程上下文。

内核栈的使用受到限制。

下半部 (Bottom Half):

延后执行的任务,用于处理中断相关的非紧急或耗时操作。

运行在非中断上下文中,这意味着:

可以睡眠。

优先级低于进程上下文,但高于普通进程。

可以使用完整的内核栈。

中断: 是由硬件事件触发的,具有最高的优先级。 中断处理程序(上半部)会立即打断当前正在运行的任何程序(包括用户空间程序、内核线程,甚至其他中断处理程序,如果允许中断嵌套)。 中断是异步的,不可预测的。

下半部: 是由上半部调度执行的,运行在内核线程的上下文中。 下半部的执行受到内核调度器的控制,并且优先级通常低于中断处理程序。 下半部不会像中断那样立即打断程序的执行,而是通过内核调度器的抢占机制来获得 CPU 的控制权。

5、 具体介绍一下中断编写流程?

上半部:

中断触发请求:主要是在设备树里进行设备的中断信息描述,包括指定中断控制器,中断触发方式(电平触发、边缘触发)等。

申请中断:使用irq_of_parse_and_map ()从设备树中获取中断号,request_irq()申请中断,参数包括中断处理函数、中断号、触发方式;

释放中断:free_irq()驱动退出释放中断;

下半部:

软中断:softirq_vec结构体数组定义默认软中断类型,使用open_softirq()传入软中断编号和软中断处理函数,使用raise_softirq()触发软中断。open_softirq() 函数负责将你的自定义软中断处理程序注册到 softirq_vec 数组中。 当你调用 open_softirq() 时,内核会将你的 action 函数指针存储到 softirq_vec 数组的相应条目中。

Tasklet:linux内核使用tasklet结构体来进行表示,结构体主要包括要执行的函数、函数的参数等,使用tasklet_init()函数tasklet初始化,传参为处理函数和函数的参数。在上半部中断处理函数里面使用tasklet_schedule(&testtasklet)开启tasklet调度。

中断线程化:my_irq=request_threadedirq(irq, thread_irq);

wake_up_process(my_thread);

工作队列:定义工作结构体,使用INIT_WORK(&testwork, testwork_func_t)加入工作,并在上半部中断处理函数里面使用schedule_work ()开启调度。schedule_work() 通过将任务添加到系统工作队列,并唤醒 worker thread,实现了异步任务的调度。 系统工作队列的 worker threads 由内核的进程调度器 (如 CFS) 来调度,并允许并发执行不同的工作项。

软中断、tasklet和工作队列的区别:

Tasklet是软中断的一个抽象层,简化了软中断的使用,提供了更方便的api,不需要手动管理和手动触发软中断;

工作队列发生在进程上下文,延迟更高,但运行睡眠,对一些长时间运行、阻塞、非中断相关任务使用工作队列。比如需要访问用户空间内存的任务。

什么是CFS (Completely Fair Scheduler)完全公平调度:

CFS 是一种复杂但高效的进程调度器,旨在为 Linux 系统提供公平的 CPU 时间分配。 它通过使用虚拟运行时间、红黑树和动态调整等机制,实现了公平性、交互性和响应性。

核心概念和原理:

公平性 (Fairness): CFS 尝试确保每个进程都获得公平的 CPU 时间份额。 这并不意味着每个进程在任何给定的时间都获得相同的 CPU 时间,而是指在足够长的时间范围内,每个进程获得的 CPU 时间比例应该与其权重(优先级)成正比。

虚拟运行时间 (Virtual Runtime - vruntime): CFS 使用虚拟运行时间 (vruntime) 来跟踪每个进程的运行时间。 vruntime 是一个经过加权的运行时间,权重取决于进程的 nice 值 (或优先级)。 nice 值较低 (例如,-20) 的进程 vruntime 的增长速度较慢,而 nice 值较高 (例如,19) 的进程 vruntime 的增长速度较快。

红黑树 (Red-Black Tree): CFS 使用红黑树来组织就绪的进程。 红黑树是一种自平衡二叉搜索树,能够高效地插入、删除和查找节点。 在 CFS 中,红黑树的键是 vruntime。

选择下一个运行进程: CFS 总是选择红黑树中最左边的节点作为下一个运行的进程。 由于红黑树是按照 vruntime 排序的,因此最左边的节点就是 vruntime 最小的进程,也就是“最饥饿”的进程,或者说最需要运行的进程。

动态调整: CFS 能够动态调整调度决策,以适应不断变化的系统负载和进程行为。

工作流程:

进程创建/唤醒: 当一个进程创建或从睡眠状态唤醒时,它的 vruntime 会被初始化或更新。

进程运行: 当一个进程运行时,它的 vruntime 会不断增加。

时间片分配: CFS 将 CPU 时间划分成时间片。 时间片的长度是动态调整的,取决于系统中就绪进程的数量。 进程运行一个时间片后,调度器会检查是否有更应该运行的进程。

重新调度: 如果有更高优先级的进程就绪,或者当前进程的时间片用完,CFS 会触发重新调度。 重新调度包括以下步骤:

将当前运行的进程插入到红黑树中 (根据其 vruntime)。

从红黑树中选择 vruntime 最小的进程 (最左边的节点) 作为下一个运行的进程。

切换到新的进程。

高通面试:

6、 linux内核空间和用户空间的通讯方式

7、 为什么中断不能睡眠

8、 内核的内存分配方式(伙伴系统、slab等等)

9、 kmalloc最小内存分配,预期分配128字节实际多少?

10、 define和const区别,分别什么时候生效?

11、 大小端的区别?

12、 cache一致性?

13、 cache的三级缓存知道吗?

14、 堆栈区别?

15、 介绍一下DMA?具体原理是什么?

16、 虚拟地址到物理地址的转换?

17、 MMU的具体工作流程?页表大小?

18、 进程的上下文具体指什么?

19、 char const* p有什么特点?

20、 Static、volatile的作用?

21、 结构体和联合体的c语言位段区别?

22、 Define和typedef的区别?

23、 C语言函数里面如何定义多个名字相同的变量?变量作用域?比如for里面进行定义变量?

函数func内有两个名为num的变量,一个在内层代码块({}内),一个在外层代码块。在内层代码块中,num的值为20,当离开内层代码块后,访问的num是外层代码块中定义的num,值为10。这是因为 C 语言中变量的作用域是从定义处到包含它的最内层代码块结束,当存在重名变量时,在各自的作用域内使用自己定义的变量。

24、 c的函数的入参是存放在哪里?所有入参都是栈吗?

25、 栈是系统哪里分配的?

26、 c语言位段了解吗?

27、 define宏为什么要加括号?

28、 锁的类型有哪些?

29、 系统调用用户态到内核态会发生什么?

30、 linux进程通讯方式?

31、 linux内核如何获取用户态pid?

32、 linux内核调度机制?

33、 linux驱动第一个被执行的函数如何实现?为什么有了__init和__exit就会去执行对应的函数?

34、 32位的linux的虚拟内存空间的分布情况?高端内存映射区是什么?他的地址是什么?

35、 用户态堆栈在系统调用时会发生什么变化吗?

36、 Arm v8 有多少个寄存器?有几种模式?异常等级有几种?工作模式有哪些?arm上电复位后进入哪种模式?

37、 知道哪些调试方法?gdb调试怎么调用函数?怎么设置打印16位的变量?怎么跟踪变量,变量值改变时自动提示?如何设置断点?死机重启怎么调试?

38、 知道trace调试吗,知道怎么用吗?

39、 Linux操作系统的三大块了解吗?

40、 现在让你开展一个项目,主要负责生物语言识别,你该怎么开展?

景嘉微面试:

41、 互斥锁和自旋锁能套着用吗?

42、 怎么结合数组和链表的优点?知道哈希数据结构吗?

43、 具体介绍一下红黑树?红黑树除了查找效率高还有什么其他优点?

44、 知道cpu具体怎么执行可执行文件的吗?

45、 知道堆数据结构吗,具体介绍一下堆排序。

零跑:

46、 递归锁了解吗?具体介绍下读写锁,读的时候能写吗

47、 线程间通知事件用什么方式?

48、 实现read函数有什么具体要注意的吗,返回值?

49、 epoll在内核层面可读通知的方法?等待队列?

50、 plantform具体的底层匹配流程以及probe执行流程?

51、 内核空间向用户空间的内存映射方式有哪些?

52、 i2c为什么用开漏输出?

小鹏:

53、 bootloader是哪里加载的

54、 芯片启动流程

55、 详细介绍一下TA的加载流程

56、 芯片架构

57、 所有的CA都能访问TA吗,如何控制CA对TA的访问权限

完结!有任何问题欢迎私信讨论

#面试问题记录##牛客创作赏金赛#
全部评论

相关推荐

不愿透露姓名的神秘牛友
11-25 09:53
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务