我一直在研究操作系统概念,并决定研究这些东西是如何在Linux中实际实现的。但是,在启动page_allocator
之前,我在启动过程中遇到与内存管理有关的问题,更准确地说bootmem
如何工作。我不需要它的确切运作,只需要理解一些事情是如何解决的。
很明显,bootmem
不能使用动态内存,这意味着他必须在运行时之前知道它的大小,因此可以采取适当的步骤,即必须事先知道其位图的最大大小。据我所知,这很可能只是通过在内核初始化期间映射足够的内存来解决,如果架构发生变化,只需更改映射内存的大小即可。显然,可能会有更多的事情发生,但我想我有了一般的想法?然而,对我来说真正没有意义的是NUMA架构。我读到的每个地方都说,为每个内存节点创建了pg_data_t
。这个pg_data
被放入一个列表中(它如何知道列表的大小?或者是特定arch的大小是固定的?),并且为每个节点分配位图。所以,基本上,它听起来像是可以创建这些pg_data
的未定义数量,每个bootmem
都有任意大小的内存位图。怎么样?我错过了什么?
mm/bootmem.c
代码,也可以在Hide();
Form2 form2 = new Form2();
form2.Closed += (s, args) => this.Close();
form2.Show();
中找到:http://lxr.free-electrons.com/source/mm/bootmem.c
答案 0 :(得分:0)
它取决于架构。在x86架构上,在引导过程的早期,内核会发出一个 BIOS调用 - 中断向量0xe820
陷阱的0x15
函数。这将返回一个内存映射,内核可以使用它来构建它的内存表,包括非内存(PCI或ISA)设备的漏洞等。引导程序(在内核之前)也会这样做。
请参阅:Detecting Memory
答案 1 :(得分:0)
在进一步研究之后,我认为它的工作方式是这样的:基本上,所有必要的东西都是静态分配的,即通过使用预处理器DEFINES确保bootmem
的某些部分(以及其他部分)内核)代码在特定体系结构的编译代码中存在或不存在(即使代码本身与体系结构无关)。这些DEFINES在arch /(例如arch / i386,arch / arm /等)下的架构相关源代码中指定。对于NUMA体系结构,有一个名为MAX_NUMNODES的定义,确保表示节点的结构列表(更具体地说,pg_data_t
结构列表)被分配为静态数组(然后将其视为列表)。表示存储器映射的位图显然相对较小,因为每个页面仅表示为一位,占用KB或MB。无论如何,体系结构依赖head.S
设置系统运行所需的所有必要结构(如页表),并确保将足够的物理内存映射到虚拟,以便这些位图可以适应它而不会导致页面错误(在x86 arch的情况下,初始的8MB RAM被映射,这对于内核和其他结构(如位图)来说已经足够了。