嵌入式面试高频(实战场景3)

此部分不只包含面经内容,均是实战类型不必全文背诵,有思路即可

后续收录于专栏:嵌入式/C++面试八股文

实战场景3

1 linux中内核空间及用户空间的区别⭐⭐⭐⭐⭐

Linux 中内核空间和用户空间主要有以下区别:

功能用途

  • 内核空间:是 Linux 内核运行的区域,负责管理硬件资源、调度进程、提供系统服务等关键任务,像内存管理、进程调度、设备驱动程序都在内核空间运行。
  • 用户空间:是用户进程运行的环境,用户的应用程序如浏览器、文本编辑器等都在此空间执行,主要用于实现用户的各种具体业务逻辑。

访问权限

  • 内核空间:具有最高的权限级别,能直接访问硬件和所有内存空间,可执行特权指令,对系统进行全面控制。
  • 用户空间:权限相对较低,不能直接访问硬件和内核数据结构,只能通过系统调用请求内核提供服务来间接访问硬件等资源。

内存布局

  • 内核空间:通常位于内存的高端地址,占用固定且连续的内存区域,其内存布局相对稳定,由内核开发者进行管理和分配。
  • 用户空间:位于内存的低端地址,每个用户进程都有独立的虚拟地址空间,包含代码段、数据段、堆、栈等,内存布局根据进程的需求动态变化。

2 用户空间与内核通信方式有哪些⭐⭐⭐⭐

在 Linux 中,用户空间与内核空间的通信方式有多种:

系统调用

  • 这是最常见的方式。用户程序通过调用如 open、read、write 等系统调用,陷入内核态,让内核执行特定操作。例如用户程序使用 read 系统调用从文件或设备读取数据,内核负责实际的读取操作并返回结果。

设备文件

  • 内核可以创建字符设备或块设备文件,用户程序通过对这些设备文件进行读写操作来与内核交互。比如 /dev 目录下的设备文件,用户程序向设备文件写入数据,内核中的设备驱动接收并处理;反之,从设备文件读取数据获取内核输出。

信号

  • 内核可向用户进程发送信号,通知特定事件。如 SIGINT(Ctrl+C)用于终止进程,用户进程也能通过 sigaction 等函数处理信号,实现与内核的简单通信。

proc 文件系统和 sysfs

  • /proc 是虚拟文件系统,内核将系统信息以文件形式呈现,用户程序读取这些文件获取内核数据;sysfs 类似,主要用于管理设备和驱动信息,用户程序可读写其中文件实现与内核交互。

netlink 套接字

  • 用于用户空间和内核空间的网络通信,支持多播,可在用户进程和内核模块间传递消息,常用于网络相关的配置和状态查询。

3 linux中内存划分及如何使用?虚拟地址及物理地址的概念及彼此之间的转化,高端内存概念linux中中断的实现机制,tasklet与workqueue的区别及底层实现区别?⭐⭐⭐⭐

内存划分及使用

  • Linux 内存分为内核空间和用户空间。用户空间供应用程序使用,通过 malloc、free 等标准库函数管理;内核空间由内核管理,使用 kmalloc、vmalloc 等函数分配内存。

虚拟地址与物理地址

  • 概念:虚拟地址是进程看到的地址空间,每个进程有独立的虚拟地址空间,增强了隔离性和安全性;物理地址是内存芯片上的实际地址。
  • 转化:通过页表实现。MMU(内存管理单元)根据页表将虚拟地址映射到物理地址。

高端内存

  • Linux 内核将物理内存划分为低端内存和高端内存。低端内存可直接映射到内核地址空间;高端内存无法直接映射,需要通过特定机制(如临时映射)来访问。

中断实现机制

  • 硬件产生中断信号,CPU 检测到后,根据中断向量表找到对应的中断服务程序入口,保存现场,执行中断服务程序,最后恢复现场,继续执行原程序。

tasklet 与 workqueue 区别

  • tasklet:运行在软中断上下文,执行速度快,不能睡眠,适合处理对时间敏感的小任务。
  • workqueue:在进程上下文执行,可睡眠,适合处理耗时或可能睡眠的任务。
  • 底层实现:tasklet 基于软中断实现,可在多个 CPU 上并行执行;workqueue 由内核线程处理工作项。

4 为什么要区分上半部和下半部linux中断的响应执行流程⭐⭐⭐

在 Linux 中断处理中,区分上半部和下半部主要有以下原因:

提高响应速度

  • 上半部主要负责快速处理与硬件直接相关的紧急事务,比如接收硬件信号、读取硬件状态等,完成后迅速返回,以便让 CPU 能尽快响应其他中断。
  • 下半部则负责处理可以稍微延迟的任务,如数据处理、更新系统状态等,这样可避免因在中断处理中执行过多复杂任务而导致系统响应变慢。

避免长时间阻塞

  • 如果所有中断处理都在上半部完成,可能会使中断处理时间过长,导致其他中断被长时间阻塞,影响系统的实时性和稳定性。
  • 将部分任务放到下半部,可以在合适的时候异步执行,不会阻塞中断的响应。

优化资源利用

  • 上半部执行时往往会禁用某些中断或抢占,以保证关键操作的原子性和完整性,这可能会影响系统的并发性。
  • 下半部可以在更宽松的环境下执行,能更好地利用系统资源,提高系统的整体性能。

Linux 中断响应执行流程一般是:硬件触发中断后,CPU 跳转到对应的中断向量,执行上半部代码,进行紧急处理后,标记需要执行的下半部任务,然后上半部结束,恢复被中断的程序执行。在合适的时机,如 CPU 空闲或满足特定条件时,会执行下半部任务,完成中断相关的后续处理。

5 谈谈Linux的同步机制⭐⭐⭐⭐⭐

Linux 的同步机制主要用于确保多个进程或线程在访问共享资源时的一致性和正确性,常见的同步机制如下:

原子操作

  • 对单个变量的操作具有原子性,在执行过程中不会被打断,如对整数的自增、自减等操作,可通过硬件指令实现,用于简单的计数或标志位操作。

自旋锁

  • 当一个进程获取自旋锁时,如果锁已被占用,它会一直循环等待,不断检查锁是否可用,适用于锁的持有时间短、不希望进程睡眠的场景。

互斥锁

  • 与自旋锁类似,但当进程无法获取锁时会进入睡眠状态,直到锁被释放,适合锁的持有时间较长的情况,能避免进程空转浪费 CPU 资源。

信号量

  • 可以控制多个进程对共享资源的访问数量,通过一个计数器来实现,进程获取信号量时计数器减一,释放时加一,当计数器为 0 时,其他进程只能等待。

条件变量

  • 通常与互斥锁配合使用,用于实现进程间的条件等待,当某个条件不满足时,进程可以等待在条件变量上,直到其他进程改变条件并唤醒它。

6 /dev/下面的设备文件是怎么创建出来的⭐⭐⭐

在 Linux 系统中,/dev 下面的设备文件主要通过以下几种方式创建:

手动创建

  • 使用 mknod 命令可以手动创建设备文件,需要指定设备类型(字符设备或块设备)、主设备号和次设备号等参数。例如 mknod /dev/mydevice c 100 0 可创建一个主设备号为 100、次设备号为 0 的字符设备文件 /dev/mydevice。

自动创建设备文件

  • udev 机制:系统启动时,udev 守护进程会扫描系统中的硬件设备,根据设备信息和规则文件在 /dev 目录下自动创建设备文件。它可以根据设备的属性,如设备名称、序列号等,为设备文件设置合适的权限、所有者和组等属性。
  • sysfs 配合 udev:sysfs 文件系统提供了系统设备的层次化视图,udev 可以从 sysfs 中获取设备的详细信息来决定如何创建设备文件。例如,当插入一个 USB 设备时,sysfs 会新增相应的设备节点,udev 监测到后根据规则在 /dev 下创建对应的设备文件。

模块加载创建

  • 内核模块在加载时,也可以通过调用内核函数来创建设备文件。例如,驱动程序可以使用 class_create 和 device_create 函数来创建字符设备或块设备文件,并将其添加到 /dev 目录中。

7 原子操作该怎么理解insmod一个驱动模块,会执行模块中的哪个函数?mmod呢?这两个函数在设计上要注意哪些?遇到过卸载驱动出现异常没?是什么问题引起的?⭐⭐⭐⭐

原子操作理解

  • 原子操作指不可被中断的一个或一系列操作,在执行过程中不会被其他进程或线程干扰,确保数据一致性。比如在多线程环境对共享变量自增,若用原子操作,可避免竞态条件。

insmod 与 rmmod 执行函数

  • insmod加载驱动模块时,执行module_init()指定的初始化函数,负责注册设备、分配资源等初始化工作。
  • rmmo

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

嵌入式/C++面试八股文 文章被收录于专栏

该专栏面向嵌入式开发工程师、C++开发工程师,包括C语言、C++,操作系统,ARM架构、RTOS、Linux基础、Linux驱动、Linux系统移植、计算机网络、数据结构与算法、数电基础、模电基础、5篇面试题目、HR面试常见问题汇总和嵌入式面试简历模板等文章。超全的嵌入式软件工程师面试题目和高频知识点总结! 另外,专栏分为两个部分,大家可以各取所好,为了有更好的阅读体验,后面会持续更新!!!

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务