OS X、gcc、x86、分段、分页、段错误、总线错误
对于 osx、gcc、现代 x86:
如何使用 x86 分段硬件和分页硬件?
In the case of osx, gcc, modern x86:
How is the x86 segmentation h/w and paging h/w used?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在大多数情况下1,不使用分段硬件。当前大多数操作系统将 CS、DS、SS 和 ES 设置为全部指向所有内存(基地址为 0,限制为 4Gig)。每个都设置为允许完全访问所有内存(CS->执行、DS、ES、SS->读/写)。
这意味着几乎所有真正的访问控制都是通过寻呼单元完成的。基本思想是将特定进程可访问的页面映射到该进程。虚拟内存中的页面被映射,但标记为不存在,因此尝试读/写它们将导致异常;操作系统将页面文件中的数据读入 RAM,将数据标记为存在,然后重新启动指令。
至于如何标记页面,大多数可执行代码将被标记为只读,并将在进程之间共享。大多数数据和堆栈将被标记为读/写并且不会被共享。根据具体的系统,堆栈空间通常会设置 NX 位以防止其被执行。
还有一些其他的细节有点不同。例如,大多数操作系统(包括 OS/X,如果内存可用)都会设置堆栈保护页 - 位于堆栈顶部的不允许访问的页面。当/如果您尝试访问它时,操作系统会捕获异常,分配另一页堆栈空间,然后重新启动指令。这意味着您可以为堆栈分配(比如说)4 MB 的地址空间,但只为大致已使用的空间分配实际 RAM(显然以页面大小的增量)。
硬件还支持“大”(4 兆字节)页面。它们主要用于映射大块连续内存,例如显卡上 CPU 直接可见的内存部分。
这只是一个非常的高级视图,但是在不知道您关心什么的情况下很难提供更多细节。试图涵盖整个操作系统对分页的所有使用可能会占用一整本书(大)。
1 Windows(与大多数其他系统不同)确实很少使用分段——它将 FS 设置为指向线程信息块 (TIB) 的指针,该指针可以访问有关当前线程的一些基本信息。线。这非常有用(并且被使用),特别是对于 Windows 的结构化异常处理(和向量异常处理)。
For the most part1, the segmentation hardware isn't used. Most current OSes set CS, DS, SS, and ES to all point to all memory (base address of 0, limit of 4Gig). Each is set to allow full access to all that memory (CS->execute, DS, ES, SS->read/write).
That means nearly all real access control is done with the paging unit. The basic idea is that pages accessible by a particular process are mapped to that process. Pages that are in virtual memory are mapped, but marked not present, so attempting to read/write them will cause an exception; the OS reads the data from the paging file into RAM, marks the data as present, and re-starts the instruction.
As far as how pages are marked, most executable code will be marked read-only, and will be shared between processes. Most data and stack will be marked read/write and will not be shared. Depending on the exact system, stack space will usually have the NX bit set to prevent it from being executed.
There are a few other bits and pieces that are a bit different. For example, most OSes (including OS/X, if memory serves) set up a stack guard page -- a page at the top of the stack that allows no access. When/if you try to access it, the OS catches an exception, allocates another page of stack space, and re-starts the instruction. This means you can allocate (say) 4 megabytes of address space for the stack, but only allocate actual RAM for roughly the space that's been used (obviously in page-sized increments).
The hardware also supports "large" (4 megabyte) pages. These are used primarily for mapping large chunks of contiguous memory like the part of the memory on the graphics card that's directly visible to the CPU.
That's only a very high-level view, but it's hard to provide more detail without knowing what you care about. Trying to cover all the use of paging by an entire OS could occupy an entire (large) book.
1 Windows (unlike most other systems) does make a minimal use of segmentation -- it sets up FS as a pointer to a Thread Information Block (TIB), which gives access to some basic information about the current thread. This is useful (and used) particularly by Windows' Structured Exception Handling (and Vectored Exception Handling).