嵌入式高频八股:操作系统篇

启动流程

为什么两次初始化DDR

  1. 第一次是BOOTLOADER初始化DDR,使其从不可用到可用,保证可以正常的引导和加载操作系统,会将UBOOT的BL1从FLASH中拷贝到DDR中执行。
  2. 第二次是LINUX启动过程中对DDR进行更加细致的初始化,并且将DDR的内存配置与内核的内存管理需求匹配。

UBOOT启动流程

【ARM-LINUX开发】U-BOOT启动过程--详细版的完全分析 - ZHANGPYI - 博客园 (CNBLOGS.COM)

中断

中断类型

  • 中断
    • 可屏蔽
    • 不可屏蔽
  • 异常
    • 陷阱(TRAP) 系统调用、信号
    • 故障(FAULT) 缺页异常
    • 错误

GIC中三种中断

  • SPI 共享外设中断
  • PPI 私有外设中断
  • SGI 软件生成中断

SGI通过软件向GIC的SGIR寄存器写值来产生中断,GIC根据内容分发给特定核心

ISR中断服务函数

ISR(INTERRUPT SERVICE ROUTINE),即中断服务程序,是处理器在响应硬件中断时执行的特殊函数。它用于处理硬件事件,并在完成后返回正常的程序执行流。ISR是嵌入式系统和实时操作系统中的关键组件。

  • 快速执行
  • 不使用阻塞操作
  • 避免使用全局变量
  • 嵌套中断

软中断

LINUX中断(INTERRUPT)子系统之五:软中断(SOFTIRQ)-阿里云开发者社区 (ALIYUN.COM)

软中断与软件中断

软中断 软件中断
用途 LINUX内核提供的延时处理机制
分离较为复杂的工作推迟处理
系统调用、异常处理、虚拟化环境通信
触发方式 硬中断或者其他部分触发 特定指令触发
执行环境 特定调度时机 中断上下文

硬件怎么告诉驱动信息来了

中断。继续回答中断的流程。一般是通过一个硬件引脚,发送给GIC控制器,然后捕获这个中断信号,GIC管理优先级排序和消息分发给对应的CPU,然后CPU会进入中断处理函数处理,这个函数一般是驱动注册的回调函数去区里,然后清除掉中断,CPU恢复继续去执行

中断初始化时需要设备树信息,是不是需要去解析它

是的。 在嵌入式系统中,设备树通常用于描述硬件配置,如中断控制器、GPIO、中断号等。当一个设备驱动初始化时,它会从设备树中提取相关的硬件信息,这包括中断相关的属性。具体步骤大致如下:

  1. 设备树节点描述:设备树中每个设备节点都可能包含中断信息,通常使用属性如 INTERRUPTSINTERRUPT-PARENT。中断控制器也通过设备树节点描述其类型和配置。
  2. 解析设备树:内核启动时,内核设备树解析器会根据设备树的内容建立硬件信息,特别是中断控制器的信息。然后设备驱动可以通过特定的 API 来读取和解析设备树中的中断号和触发类型。
  3. 调用 DT 解析 API:LINUX 内核提供了相关 API,比如 OF_IRQ_GET()IRQ_OF_PARSE_AND_MAP() 等,这些函数帮助驱动从设备树中提取和映射中断号。驱动程序会调用这些 API 获取设备树中的中断信息。
  4. 中断注册:在解析出设备树中的中断信息后,驱动程序会使用 REQUEST_IRQ() 等 API 注册中断处理函数。

中断中为什么不可以睡眠?

面试官:为什么在中断里不能 SLEEP | LINUX 内核 - 知乎 (ZHIHU.COM)

  1. 中断是在中断上下文中,与任何的进程上下文无关
  2. 内核代码里有大量的 CRITICAL SECTION (临界区),如果想要支持 CALL SCHEDULER 的话,那么所有的 CRITICAL SECTION 都必须得禁用中断,否则硬件中断一旦来临系统就会出现 RACE CONDITION,接下来大概率是死锁。但是这样的中断响应延迟就很大。

内存管理

内存碎片的类型

  • 外部碎片:内存有足够的内存,但是由于空闲空间被分成多个不连续小块,无法满足分配大的内存空间
  • 内部碎片:分配的内存块比实际需求大的多,多出来的部分无法使用

内存碎片产生的原因、有哪些场景产生、怎么解决

产生原因:

  • 外部碎片:内存有足够的内存,但是由于空闲空间被分成多个不连续小块,无法满足分配大的内存空间
  • 内部碎片:分配的内存块比实际需求大的多,多出来的部分无法使用

场景:

  • 频繁的动态分配和释放内存
  • 操作系统分配内存可能产生碎片
  • 虚拟内存系统将物理内存映射到虚拟地址空间时

解决方式:

  • 优化算法
    • 首次适配(FIRST FIT):找到第一个能满足要求的空闲块进行分配。
    • 最佳适配(BEST FIT):找到最接近所需大小的空闲块进行分配,减少外部碎片。
    • 最坏适配(WORST FIT):找到最大的空闲块进行分配,尝试保留大块空间以减少未来的外部碎片。
  • 伙伴算法
  • SLAB算法
  • 垃圾回收
  • 内存压缩:适当的时候进行整理
  • 内存池

伙伴算法的优缺点

优点

  • 分配速度快,分割和合并效率简单高效
  • 减少外部碎片
  • 内存对齐 缺点
  • 依旧存在内部碎片
  • 内存利用率不高(内部碎片的问题)
  • 复杂性

环形缓冲区怎么判断空、满

环形缓冲区有BEGIN END两个指针,当

  • 空 BEGIN=END
  • 满 BEGIN->NEXT=END

内存泄漏

总的来说一句话,分配了内存没有释放。

  • NEW 没有FREE
  • 循环引用,计数器无法归零
  • 丢失指针

解决办法:

  • 分配后释放
  • 智能指针
  • 避免循环引用

工具:

  • ADDRESSSANITIZER
  • VALGRIND

内核空间与用户空间之间的内存拷贝

通过COPY_TO_USER()COPY_FROM_USER,在拷贝的时候会进行地址的检测,是否指向有效的用户空间内存区域,以及确保访问不会越界。然后操作系统内核会使用 CPU 的特权模式来访问用户空间的内存地址。因为进入内核的时候页表不会改变,依旧用的是用户进程的页表(所有进程的内核空间映射是同一个位置,用户态进入内核态不需要切换页表)。这些地址通过 MMU 进行转换,映射到物理内存,然后内核通过物理内存地址进行读写操作。由于用户空间的内存地址可能是虚拟地址,内核需要通过页表进行转换,找到对应的物理地址。这个过程是由硬件 MMU 和操作系统联合完成的。

总结:通过特定函数,内核以特权模式直接向用户空间虚拟地址指向的物理地址进行拷贝。

应用层随便写个地址,内核是怎么检测出异常的

进程在创建的时候会先将分配好自己所需要的虚拟地址空间,但是此时并没有对实际的物理地址分配映射,后续需要的时候才会分配,所以可以区分下面两种来对检测异常做解释:

  • 缺页异常:发现需要访问的地址在已经分配的虚拟地址空间内,但是没有映射到物理地址,就会触发缺页异常,然后分配物理地址做出映射,放到页表中方便后续使用。
  • 段错误:发现需要访问的地址超出了虚拟地址的空间,或者超过了堆栈的范围,或者是访问的页面权限不符,就会认为是一个错误地址。

IOMMU的作用与意义

作用:

  1. 地址转换:
    • IOMMU 为 I/O 设备提供虚拟地址空间支持,类似于 CPU 使用 MMU 来管理进程的虚拟地址空间。IOMMU 将设备发出的虚拟地址转换为物理地址,使设备可以访问系统内存,而不需要知道物理内存的实际布局。
    • 这种地址转换还允许设备在被重新配置时,不需要修改其所使用的内存地址,只需修改 IOMMU 的映射即可。
  2. 内存保护:
    • IOMMU 提供了一个安全层,通过限制设备可以访问的内存区域,防止设备意外或恶意地访问其他进程或内核空间的内存。
    • 这种保护对防止 DMA(DIRECT MEMORY ACCESS,直接内存访问)攻击特别重要,因为攻击者可能试图利用 DMA 设备直接访问内存,从而绕过操作系统的安全机制。
  3. 设备隔离:
    • 在虚拟化环境中,IOMMU 可以帮助实现虚拟机对物理设备的隔离。它允许虚拟机使用物理设备的虚拟化版本,同时确保这些设备只能访问分配给它们的内存区域。
    • 这种隔离对于确保虚拟机之间的安全性至关重要,因为它防止了一个虚拟机能够通过设备访问其他虚拟机的内存。
  4. 提高系统性能:
    • 在多核和多设备的复杂系统中,IOMMU 可以优化内存访问路径,使得 I/O 操作更高效,减少 CPU 处理内存访问的负担。
    • 通过 IOMMU,设备可以直接访问系统内存,而无需通过中介或额外的内存拷贝,这种直接访问(DMA)可以显著提高数据传输速率。

意义:

  1. 安全性增强:
    • IOMMU 是现代计算机系统安全架构中的关键组成部分。它通过防止设备对不安全内存区域的访问,大大提高了系统的安全性。尤其是在

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

1. 自我介绍:高通、Oppo(sp)、vivo(sp)、小米(ssp)、荣耀(26k*12+80k)、华子(报批中)、美团、韶音、经纬恒润、乐鑫、中兴、TP 2. 内容: 1.嵌入式学习的资料和路径 2.所有面试的题目和解答(持续更新)、对评论的快速解答 3.各种碎碎念 3.整理不易,buy me coffee☕️,为了回馈牛客和各个粉丝,文章都会先试读几天,热度过了再收录~

全部评论

相关推荐

1. 实时数据采集  在嵌入式系统中,如何有效地实现实时数据采集?请列出关键步骤和考虑因素。2. UART通信注意事项  在使用UART进行设备间通信时,需注意哪些事项以确保数据传输的可靠性?3. FreeRTOS任务延时  在FreeRTOS中,如何实现任务的延时功能?请给出具体的API和示例。4. SPI数据交换  如何通过SPI与传感器进行数据交换?请描述配置和数据传输的过程。5. TCP/IP协议栈配置  在嵌入式系统中,如何配置和使用TCP/IP协议栈以实现网络通信?6. PWM控制伺服电机  如何使用PWM信号控制伺服电机的角度?请说明具体的实现方法。7. FreeRTOS互斥量  在FreeRTOS中,如何实现互斥量的使用以保护共享资源?8. 低功耗模式实现  在嵌入式系统中,如何实现低功耗模式?请列出可采取的策略。9. I2C温度传感器读取  如何使用I2C与温度传感器进行数据读取?请描述具体的步骤。10. FreeRTOS任务通知机制  在FreeRTOS中,如何实现任务的通知机制以同步任务间的操作?11. ADC配置  如何配置ADC以读取温度传感器的数值?请列出配置步骤。12. 数据压缩实现  在嵌入式系统中,如何实现数据压缩以节省存储空间?13. PWM控制电机速度  使用PWM控制电机速度的基本原理是什么?请解释其工作机制。14. 优先级反转  在FreeRTOS中,如何处理任务的优先级反转问题?请给出解决方案。15. 中断处理按键输入  如何使用中断来处理按键输入?请描述具体的实现过程。16. CRC校验实现  在嵌入式系统中,如何实现数据的CRC校验?请提供算法和步骤。17. CAN总线通信原理  使用CAN总线进行车辆数据通信的基本原理是什么?请简述其工作流程。18. FreeRTOS事件组  在FreeRTOS中,如何实现事件组的使用以管理多个任务的同步?19. 外部中断响应  如何使用外部中断来响应传感器数据变化?请说明具体的配置和实现。20. 压力传感器读取  在嵌入式系统中,如何实现压力传感器的读取?请描述相关步骤。21. DMA音频数据传输  使用DMA进行音频数据传输的优势是什么?请说明其实现方法。22. 软件定时器使用  在FreeRTOS中,如何实现软件定时器的使用以定时执行任务?23. 图像传输实现  在嵌入式系统中,如何实现图像传输?请列出所需的协议和步骤。24. RTC定时事件调度  如何使用RTC进行定时事件的调度?请描述配置和使用方法。25. 内存使用监控  在FreeRTOS中,如何监控内存使用情况以避免内存泄漏?26. USB设备识别  使用USB进行设备识别和通信的基本原理是什么?请简述其工作流程。27. 音频录制实现  在嵌入式系统中,如何实现音频录制?请列出关键步骤。28. MQTT设备监控  如何使用MQTT协议进行设备状态监控?请描述实现流程。29. FreeRTOS时间管理  在FreeRTOS中,如何实现任务的时间管理以优化系统性能?30. 固件安全更新机制  在嵌入式系统中,如何实现固件的安全更新机制?请列出关键考虑因素。嵌入式C++面经推荐大佬面经  链接在下边  c++/嵌入式面经专栏-牛客网 https://www.nowcoder.com/creation/manager/columnDetail/MJNwoM
点赞 评论 收藏
分享
评论
5
42
分享

创作者周榜

更多
正在热议
更多
牛客网
牛客企业服务