在内核编程方面,我是个菜鸟,我想知道是否有人能为我指明在内核设置中开始实现内存管理的正确方向。我目前正在研究一个玩具内核,并对这个问题做了大量的研究,但是我对内存管理这个话题有点困惑。它有很多不同的方面,比如分页和虚拟内存映射。是否有一个具体的顺序,我应该实现的事情或任何做的和不做的?我不是在寻找任何代码或任何东西,我只是需要指出正确的方向。任何帮助将不胜感激。
发布于 2015-10-31 19:18:34
您应该分别考虑以下几个方面:
malloc和free。要能够管理任何其他内存需求,您需要知道实际有多少物理内存可用,其中哪些部分可供您使用。假设您的内核是由一个与多引导兼容的引导加载程序加载的,您将在多引导报头中找到从引导加载程序传递的信息(如果我没有记错的话,在eax on x86中)。标头包含一个结构,描述使用哪些内存区域和哪些可以自由使用。
您还需要以某种方式存储这些信息,并跟踪分配和释放了哪些内存。这样做的一个简单方法是维护位图,其中位N指示从N * S到(N + 1) * S - 1的(固定大小的S)内存区域是使用还是空闲。当然,随着内核的发展,您可能希望使用更复杂的方法,如多级位图或空闲列表,但上面的简单位图可以帮助您开始工作。
这个内存管理器通常只提供“大”大小的内存块,通常是4KB的倍数。当然,这对于您习惯于从应用程序编程中使用的malloc和free风格的动态内存分配没有任何用处。
由于动态内存分配将大大简化内核高级特性的实现(多任务处理、进程间通信、.)通常编写内存管理器,特别是为内核编写内存管理器。它为任意大小的内存块的分配(kalloc)和去分配(kfree)提供了手段。此内存来自使用上述物理内存管理器分配的池。
所有这些都发生在内核内部。您可能还希望提供应用程序方法来执行动态内存分配。实现这一点在概念上与上面所做的物理内存管理非常相似:
进程只看到自己的虚拟地址空间。它的某些部分对于进程是不可用的(例如,内核内存映射到的区域),但大部分部分将“免费使用”(也就是说,没有实际的物理内存与其相关联)。内核至少需要提供应用程序来分配和释放其内存地址空间的单个页面。在调用物理内存管理器和从请求的页面到这个新分配的内存的映射中,分配页面结果(应用程序不可见)。
但是请注意,许多内核提供了它的进程,要么更复杂地访问自己的地址空间,要么在内核中直接实现以下一些任务。
能够像以前一样分配和释放页面(主要是4KB)无助于动态内存管理,但这通常是由其他内存管理器处理的,它使用这些大内存块作为池向应用程序提供较小的块。一个突出的例子是道格·利亚(氏)分配器。像这样的内存管理器通常被实现为库(很可能是标准库的一部分),并链接到每个应用程序。
https://stackoverflow.com/questions/33447708
复制相似问题