在内核编程方面,我有点像菜鸟,并且想知道是否有人能指出我在内核设置中开始实现内存管理的正确方向。我目前正在研究玩具内核,并且正在对这个主题进行大量研究,但我对内存管理这个话题感到有点困惑。它有很多不同的方面,如分页和虚拟内存映射。是否有特定的命令我应该实施的事情或任何不做的事情? 我没有找到任何代码或任何东西,我只需要指出正确的方向。任何帮助都将不胜感激。
答案 0 :(得分:2)
您应该分别考虑多个方面:
malloc
和free
。为了能够管理任何其他内存需求,您需要了解实际可用的物理内存量以及可供您使用的部分内存。
假设您的内核由多引导兼容的引导加载程序加载,您将在引导加载程序中通过multiboot header中找到此信息(如果我没记错的话,在x86上的eax
中)。
标题包含一个结构,描述了使用哪些内存区域以及哪些内存可以自由使用。
您还需要以某种方式存储此信息,并跟踪分配和释放的内存。一种简单的方法是维护位图,其中位N
指示是使用S
到N * S
的(固定大小(N + 1) * S - 1
)内存区域还是空闲的。当然,您可能希望在内核进展时使用更复杂的方法(如多级位图或空闲列表),但如上所述的简单位图可以帮助您入门。
这个内存管理器通常只提供" large"大小的内存块,通常是4KB
的倍数。对于您在应用程序编程中习惯使用的malloc
和free
样式的动态内存分配当然没有用。
由于动态内存分配将极大地简化内核的高级功能(多任务,进程间通信......),因此通常会为内核编写内存管理器。它提供了任意大小的内存块的分配(kalloc
)和释放(kfree
)的方法。此内存来自使用上面的物理内存管理器分配的池。
以上所有内容都发生在内核中。您可能还希望提供应用程序来进行动态内存分配。实现这一点在概念上与物理内存管理非常相似,如上所述:
进程只能看到自己的虚拟地址空间。它的某些部分对于进程是不可用的(例如内核内存映射到的区域),但是大多数部分将是"可以自由使用" (也就是说,实际上没有物理内存与它相关联)。至少内核需要提供应用程序来分配和释放其内存地址空间的单个页面。在调用物理内存管理器时,以及从请求的页面到新分配的内存的映射中,分配页面(在引擎盖下,对应用程序不可见)。
请注意,许多内核为其进程提供了更复杂的访问权限,或者直接在内核中实现以下某些任务。
能够像以前一样分配和释放页面(主要是4KB
)对动态内存管理没有帮助,但是像以前一样,这通常由使用这些大内存块的其他内存管理器处理作为池,为应用程序提供较小的块。一个突出的例子是Doug Lea's allocator。像这样的内存管理器通常实现为链接到每个应用程序的库(最有可能的标准库的一部分)。