我已经阅读了很多关于虚拟地址和分页的内容。 我先告诉大家我的理解。当进程想要执行某些操作时,它会尝试将数据从硬盘加载到内存中。为此,它使用虚拟地址。所以我们的MMU验证虚拟地址查看TLB以找到相应的物理页面,如果找不到它,它会查看Inverted Page Table,最后它会查看Page表,如果它没有在那里找到一个条目它会生成页面错误,并且页面的所有交换都已完成,所有表格都将更新。 当我读到所有进程有不同的页表和相同的虚拟地址。因此,如果我尝试访问一个数组元素a [1000],它被定义为int a [100]我肯定会得到一个分段错误,因为该指令可能试图访问不属于它的内存。但OS如何通过仅使用虚拟地址和物理页面的概念来了解[1000]不属于正在运行的进程。我在这里遗漏了什么或者我的理解是错的吗?
我知道如果进程试图访问只读或超级内存段,我们可以说内存访问是非法的。
最后,沸腾的问题是操作系统如何决定将哪个内存分配给哪个进程以及它如何决定这种内存访问是非法的。
What is a segmentation fault on Linux?
此链接没有多大帮助。
非常感谢所有可爱的人们的投入:)
答案 0 :(得分:1)
实际上Linux内核中的每个进程都有一些与之关联的定义良好的结构,称为task_struct,它存储有关相应进程的所有信息,如其父进程,PID,子进程,地址空间,挂起信号,线程关联现在,地址空间条目告诉内核在执行进程时该进程的合法地址空间。每个进程都有自己的内核地址空间,从创建之初就由内核分配给它。因此,当执行进程尝试访问其合法内存之外的空间时,会生成错误(在Unix/Linux
中称为分段错误),并且通过内核向其发出信号来终止进程。它对于在操作系统中实现内存保护非常重要。
答案 1 :(得分:0)
在x86上,linux使用分段和分页的组合,因此程序生成的地址首先查找相应的段base和limit寄存器值。这给出了虚拟地址,然后使用页表进行翻译。当您尝试访问尚未分配的内存时,访问的页面超出了限制寄存器允许的范围,因此会生成分段错误。