我的工作核心的设计,我已经有了一些有关的问题分页。

基本想法,我们迄今为止是这样的:每个计划都有自己的(或因此,它认为)4G的存,减去一部分的地方,我保留对核心功能的应用程序可以调用。所以,操作系统需要找出一些方法来装载网页在内存方案需要使用在其运作。

现在,假定我们不得不无限量的存储和处理的时间,我可以载有分配任何页的计划中写道或读取,因为它发生的使用缺页的页面不存在(或被换出)所OS可能快地将它们分配或交换他们。在现实世界中,需要优化这个过程,所以,我们没有一个程序不断地消耗所有的存储器,它曾经感动。

所以我想我的问题是,如何操作系统的一般去吗?我最初的想法是建立一个功能,该计划呼吁设定的/免费的网页,然后,它可以存储管理自己,但没有一个程序通常这样做,或者没有编译器的假定它具有免费的统治?此外,如何编译器处理的情况需要拨出相当大的一段记忆?我需要提供的功能,试图给它的X页,以便?

这显然不是一个语言的具体问题,但我偏标准的C和良好的用C++,所以我想任何代码的例子可以在任何一,或大会。(大会不应该是必要的,我完全打算使其工作尽可能多的C代码成为可能,并优化其作为最后的步骤。)

另一件事应该是容易回答,以及:如何不会一个一般处理核心的功能,这一程序需要电话吗?那是正确的,只要有一套区域的存储器(我想朝向结束的虚拟空间),其中包含最基本的功能/处理特定的存储程序可以打电话?我想从那里将是具有核心功能做一些非常花哨和交换页(所以这一程序不能看到敏感核心职能在他们自己的空间)当程序需要做什么重大,但我不是很注重安全,在这一点上。

所以我想我更担心的一般设计想法比的具体情况。我想让内核完全兼容的海湾合作委员会(以某种方式)和我需要确保它提供了一切正常程序的需要。

谢谢你的任何建议。

有帮助吗?

解决方案

一个良好的起点,所有这些问题是看Unix如何做它。正如一句名言说:"那些不了解UNIX是注定要重新改造它,不佳。"

第一,关于调用核心功能。它是不够的,只是有功能的地方程序的可以称,由于该节目是最有可能在运行中的"用户模式"(环3月IA-32)和内核运行"核模式"(通常环0IA-32)做其荣幸运作。你必须以某种方式做过渡之间的两种模式,这是非常架构的具体。

在IA-32,传统的方法是使用一个门在IDT一起与一个软件的中断(Linux用int0x80).较新的处理器还有其他(更快的)方式做到这一点,哪些是可取决于是否CPU是从AMD或者英特尔,并在具体的CPU模型。为了适应这种变化,最近的Linux内核使用的页码映的核顶部的地址空间为每个过程。因此,在最近的Linux,做一个系统称呼你叫功能上的这一页,而这些反过来又将做什么,需要切换到核心模式(核有多个复制网页,选择哪一副本上使用的启动取决于你处理器的特点)。

现在,存储管理。这是一个 巨大的 主题;你可以写一本大书关于它并不皆极的主题。

一定要记住有至少 两个 享存储器:理查看(真正的秩序的网页,可见于硬件内存子系统的和往往外围设备)和逻辑视(秩序的网页看上运行的程序的CPU)。很容易混淆这两者。你将被分配 物理 网页,并将他们分配到 逻辑 地址上的程序或核地址的空间。一个物理的页面可以有几种合乎逻辑地址,并且可以映不同的逻辑地址在不同的进程。

核心存储器(保留给内核)通常是映射在顶部的地址空间的每一个过程。然而,它的设立,使它只能acessed在内核的模式。没有必要花哨的技巧隐藏的那部分记忆;硬件不会所有工作的阻挡的访问(在IA-32,这样做是通过网页的标志或段的限制).

该项目分配存在其他的地址的空间,在几个方面:

  • 存储器的一部分是分配核的程序加载程序。这包括的程序码(或"文本"),该程序初始化数据("数据"),该程序初始化的数据("bss",零充),叠,几个可能性和结束。多少分配,在那里,什么应该是最初的内容,其保护标志的使用,及若干其他事项外,被阅读,从标题上可执行的文件加载。
  • 传统上Unix,有一个区域的存储器可以增长和收缩(其上限可以通过改变的 brk() 系统调用)。这是传统上使用的堆(存储器在C库,其中 malloc() 是的一个接口,负责堆).
  • 你经常可以要求核地图文件的一个区域的地址空间。读写这一领域是(通过呼魔法)针对背的文件。这通常被称为 mmap().有一个匿名的 mmap, 你可以分配新的领域的地址空间中哪些是不支持任何文件,但无法同样的方式。内核的程序载程序将经常使用 mmap 分配的部分程序码(例如,程序的代码可以支持通过可执行的本身)。

Acessing地区的地址的空间,没有分配任何方式(或被保留用于核)被认为是一个错误,并在Unix将导致一个信号以发送的程序。

编译器的任分配静态存储器(通过指定的可执行的文件报头;内核的程序,装载机会分配的存在加载的程序)或动态(通过调用一个功能上的语言的标准图书馆,这通常然后电话的功能在C语言标准图书馆,然后呼吁的核心分配存和细分如果必要)。

最好的方式来学习这一切都是为了阅读了几本书上操作系统,特别是那些使用Unix变为一个例子。它会在方式更详细的比我上一个答案在计算器.

其他提示

这个问题的答案是高度依赖于架构的。我假设你在谈论x86。对于x86,内核通常提供一组系统调用,它们是进入内核的预定入口点。用户代码只能在这些特定点进入内核,因此内核可以仔细控制它与用户代码的交互方式。

在x86中,有两种方法可以实现系统调用:使用中断,以及使用sysenter / sysexit指令。通过中断,内核设置中断描述符表(IDT),它定义了进入内核的可能入口点。然后,用户代码可以使用 int 指令生成一个软中断来调用内核。中断也可以由硬件产生(所谓的硬中断);这些中断通常应该与软中断不同,但它们不一定是。

sysenter和sysexit指令是执行系统调用的更快方法,因为处理中断很慢;我对使用它们并不熟悉,所以我无法评论它们是否适合您的情况。

无论您使用哪种方式,都必须定义系统调用界面。您可能希望在寄存器中而不是在堆栈中传递系统调用参数,因为生成中断将导致您将堆栈切换到内核堆栈。这意味着您几乎肯定必须在用户模式端编写一些汇编语言存根以进行系统调用,并在内核端再次编写系统调用参数并保存寄存器。

完成所有这些后,您就可以开始考虑处理页面错误了。页面错误实际上只是另一种类型的中断 - 当用户代码尝试访问没有页表项的虚拟地址时,它将生成中断14,并且您还将错误地址作为错误代码。内核可以获取此信息,然后决定从磁盘读取丢失的页面,添加页表映射,然后跳回用户代码。

我强烈建议您查看麻省理工学院操作系统

中的一些材料。一个>类。查看参考部分,它有很多好东西。

scroll top