虚拟地址、中断异常

问题1:什么是页表?为什么要有?

一、具体技术版(详细解释)

1. 什么是页表(Page Table)?

页表是操作系统和MMU(内存管理单元)用来管理虚拟内存到物理内存映射的数据结构。

  • 作用:记录虚拟地址(程序看到的地址)和物理地址(实际RAM地址)的对应关系。
  • 存储位置:通常由CPU的MMU硬件自动查询,部分嵌入式系统(如无MMU)可能由软件模拟。

2. 为什么要有页表?

  1. 内存隔离与保护
    • 每个进程有独立的虚拟地址空间,避免程序越界访问(如A进程无法篡改B进程的数据)。
    • 通过页表权限位(读/写/执行)实现硬件级内存保护(例如:代码段只读)。
  2. 虚拟内存(按需分页)
    • 允许物理内存不足时,将部分数据暂存到磁盘(Swap),页表标记页是否在内存中(Present位)。
    • 嵌入式场景:部分RTOS或无MMU系统可能禁用此功能,但Linux嵌入式系统常用。
  3. 内存碎片整理
    • 物理内存可能碎片化,但页表让程序看到连续的虚拟地址空间(如malloc分配的内存)。
  4. MMU硬件加速
    • CPU通过MMU自动转换地址,无需软件计算,提升性能(尤其对高频访问的代码/数据)。
  5. 共享内存
    • 同一物理页可映射到多个进程的页表(如库代码)。

二、面试背诵版(简练回答)

1. 页表是什么?

“页表是虚拟地址到物理地址的映射表,由MMU硬件自动转换,实现内存隔离、保护和共享。”

2. 为什么需要页表?

三个核心作用

  1. 隔离性:防止进程越界访问。
  2. 灵活性:支持虚拟内存(Swap)、内存碎片整理。
  3. 高效性:MMU硬件加速地址转换,提升性能。

3. 嵌入式场景补充

“在嵌入式Linux中,页表管理内存;裸机或无MMU系统(如某些RTOS)可能直接操作物理地址。”

三、面试加分点

  • 举例:
    • “比如STM32H7带MMU,跑Linux时需要页表;而STM32F1无MMU,跑FreeRTOS时直接访问物理地址。”
  • 扩展问题:
    • 面试官可能问:“页表转换的流程?” → 答:“CPU发虚拟地址 → MMU查页表 → 找到物理地址或触发缺页异常。”

问题2:操作系统的缺页中断完整过程?

核心流程(四步速记)

  1. CPU访问无效页
    • 程序访问的虚拟地址在页表中标记为无效(不存在或无权限)。
    • 触发原因:
      • 页未加载(Present=0)。
      • 权限错误(如写只读页)。
  2. 硬件捕获异常
    • CPU自动保存现场(寄存器、PC等),跳转到内核的缺页中断处理程序
  3. 内核处理
    • 检查地址合法性:是否属于进程的合法地址空间(否则触发SIGSEGV)。
    • 加载缺失页
      • 磁盘中加载数据到物理内存。
        • 若进程的工作集满了,通过页面置换算法,选择一页换出,再将该页写入
      • 更新页表,标记为有效(Present=1)。
  4. 恢复执行
    • 内核返回到用户态,CPU重新执行触发缺页的指令。

问题3:简述什么是虚拟内存和物理内存?为什么要用虚拟内存?

物理内存是实际的RAM硬件,而虚拟内存是操作系统为每个进程抽象的地址空间,通过页表映射到物理内存。 ​虚拟内存的三大作用​:

  1. 隔离性:每个进程都有独立的虚拟地址空间,防止进程互相干扰(如A进程崩溃不影响B进程)。
  2. 灵活性:程序可用比物理内存更大的空间(如Linux的Swap)。
  3. 安全性:通过页表标记内存为只读/可执行(防止代码被篡改或数据被非法执行)。
  4. 共享性:多个进程的虚拟地址可映射到同一物理页(如动态库代码共享)。

问题4:在有TLB、页表的系统中,虚拟地址到物理地址怎么映射的?

TLB(快表),页表(慢表)

VA(virtual address):虚拟地址,PA(physical address):物理地址

核心流程(5步)

  1. CPU发虚拟地址(VA)MMU拦截。
  2. 先查TLB(快表):
    • 若命中(TLB缓存了VA→PA映射),直接返回物理地址(PA),无需查页表
    • 若未命中,继续查页表。
  3. 查页表(Page Table):
    • 多级页表:VA分段查表,页表命中,得到逻辑页号 对应的 物理页号。
    • 若页未加载到内存,触发缺页异常,执行缺页处理程序,将逻辑页调入到内存中,得到逻辑页号对应的物理页号
  4. 更新TLB:将新查到的逻辑页号→物理页号映射存入TLB,加速下次访问。
  5. MMU返回PA

中断和异常的区别

核心区别总结

类型 触发源 触发时机 处理方式 典型场景
中断 外部硬件设备 异步(随机发生) 内核调用中断处理程序 键盘输入、定时器到期、网络包到达
异常 CPU执行指令时内部错误 同步(必然发生) 内核调用异常处理程序或终止程序 除零、非法指令、缺页中断、系统调用
#嵌入式软件开发岗##嵌入式软件开发面经##秋招##春招#

搜集全网的面试题,对每个题目,先给具体的回答,再给言简意赅版本。 具体的回答方便理解,言简意赅版本方便背诵,快速冲刺面试!

全部评论

相关推荐

一、学习方向选择以下仅代表笔者个人看法:嵌入式软件总体分为linux和mcu方向。这两个方向的应用场景不同,导致无法在同一份工作中既做Linux,又做mcu。因此,如果在时间不充裕的情况下,大家根据自身情况挑一个方向去学习就够了。mcu方向(也称为嵌入式软硬件方向)更专注于软硬件结合,也就是说除了软件部分之外,还需要懂硬件。如果在软件和硬件分的没那么开的公司,作为一名嵌入式软件工程师,不仅要自己写代码,还需要自己画原理图,画PCB。在软硬件分开的情况下,基本要求是要能看的懂电路原理图,这也是大多数转行者很容易忽视的点。linux方向由于岗位较少,通常需要驱动/内核/应用一起做,仅有部分公司或者原厂才会放出单一的岗位出来,如单独的linux驱动岗位,内核/应用岗位等,这个方向比较偏软件一点。但由于岗位较少,门槛也就稍微高一些。二、mcu方向学习路线0基础的同学建议按照步骤走(再次重申是个人看法,如果你觉得不对,就不要看下去了):1、掌握基本电路知识,重点主要为电容、电感及滤波电路,还有一个傅立叶变换(可以看刘陈版本的电路分析基础这本书或者是b站进行学习)2、模电(主要掌握二极管、稳压管、三极管、mos管、放大电路、运算放大器、反馈电路);笔者个人推荐的书籍是黄丽亚的第三版模拟电子技术基础,学完前7章就够了。当然,也可以选择其他版本的,看个人喜好。3、数电(主要掌握进制转换,反码补码、逻辑电路、触发器、寄存器、AD转换及存储器知识),推荐书籍为华中科技大学的电子技术基础(数字部分)。上述三步就是为了打牢硬件基础,能看懂电路原理图。4、接下来学习一款EDA工具的使用,不要再去学嘉立创了!企业里边只有三大EDA工具:Altium Designer/Candence/Pads,任意挑一个去学习。个人比较推荐学习AD,可以在b站上看凡亿教育的课程进行学习。5、学习C语言,个人还是推荐谭浩强红色的那本高校书籍,当然也有其他优秀课程,大家可以自行选择。C语言的学习是一个持续加深的过程,前期先掌握基础就行,需要学习的是前1-7章,第8章的指针变量/数组指针,第9章的结构体/共用体/枚举/typedef。6、学习stm32,不要再浪费时间去学51老古董了。个人推荐正点原子,资料很充足,按照资料学基本就够了。同时一定要学标准库,前期不要把精力浪费在学hal库上,hal库等后边自己看一下就行。学习方法是买一款开发板(F1/F4都可以),跟着资料一步一步学,掌握基本常用外设如串口/GPIO/定时器/中断/PWM/输入捕获/LCD/ADC/IIC/SPI/485/CAN/IAP等。ps:学习过程中不要只看,一定要做!看懂了不等于你掌握了,毕竟实践是检验真理的唯一标准!7、做完上述步骤,恭喜你已经打好基础了,进一步继续深入学习c语言的提高部分,把前边说的第8章的二维指针/数组指针/指针数组等等指针的高阶用法掌握,以及动态内存分配函数等;还有第9章的链表;此处笔者推荐看人民出版社的c和指针一书,进行c语言的加深学习。这本书需要掌握如编译的底层原理/指针的高阶用法/递归函数/单向或者双向链表/预处理器等。8、完成c语言的进阶学习之后,开始学习stm32内核,这里推荐看CM3权威指南这本资料,主要看前9章内容,至少要知道寄存器组/PendSV/SVC/systick定时器等,为学习RTOS打好基础。9、开始学习RTOS,自行挑选一款rtos进行学习(ucos/freertos/rt-thread),笔者是同时学了ucos和free,个人比较推荐从ucos学起(也是正点原子的资料),毕竟资料比较多,底层原理讲的比较细,比如任哲老师的嵌入式实时操作系统原理及应用就是以ucosii进行讲解的。当然大家也可以选择其他的,这个阶段建议还是多看资料,少看课。因此笔者并没有什么推荐的课程。ps:到这一步要开始做32和rtos的项目了,做完项目以后就可以去投实习/秋招,这个程度已经够找工作了。10、学习常用数据结构:数组/堆/栈/链表/树/哈希表/队列,图不要求掌握,树学二叉搜索树就够,在弄清楚基本数据结构以后再去力扣上进行刷题,比如要知道栈不仅可以用数组实现,还可以用链表实现。ps:这一步想进大厂必不可少,毕竟面试都是要手撕的!11、学习RTOS源码,弄清楚任务调度/任务通信/时钟及延时/内存管理等。为什么要先去学习数据结构再回来看rtos源码,就是因为其源码中包含大量链表和队列的使用,如freertos中列表与列表项中涉及到双向链表的插入和删除操作,这样才能看得懂源码。ps:到这一步已经够卷了,笔者觉得不用担心找不到工作了。接下来说的东西可以入职以后再进行学习12、其他通用中间件的学习,如网络协议(mqtt/lwip协议等),选一个进行学习。还有图形库lvgl/ewmin等,也是选择一个进行学习。学习方法也是找资料,我依然用的是正点原子。13、学习代码版本管理工具git的使用,需要掌握常用命令,如克隆,提交,上传以及创建分支等。学习方法笔者推荐是看官网。三、linux方向学习路线linux方向笔者还在摸索中,因此就简单说一下1、先学会使用linux系统,学会Linux基本命令使用,学习方法推荐b站尚硅谷。2、学习gcc、make工具链的使用及makefile脚本。3、学习c++,主要掌握面向对象特性,如类和对象/继承/重载/多态/封装/虚函数/智能指针/动态内存等。推荐书籍为c++ primer第五版以及菜鸟编程网站。4、Linux应用编程,如进程/线程、文件io、网络编程等。推荐资料--正点原子。5、学习QT开发,推荐资料正点原子。6、Linux下的裸机开发(推荐买板子学习,如imx6ull;掌握常用外设以及CortexA处理器架构),推荐资料--正点原子或者韦东山。ps:学习linux驱动需要有电路原理图能力。7、Linux驱动开发(结束裸奔,上操作系统了, 包括移植uboot/linux内核/根文件系统等、掌握Linux三大类驱动,包括字符设备/块设备/网络设备驱动),同时需要掌握GDB调试。可以看到嵌入式两个方向的内容都非常多,因此大家选一个学,找工作足够了。本次讲解就到这里,感谢观看!
点赞 评论 收藏
分享
评论
1
2
分享

创作者周榜

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