Skip to content

Latest commit

 

History

History
38 lines (23 loc) · 3.18 KB

物理内存管理.md

File metadata and controls

38 lines (23 loc) · 3.18 KB

本文档记录了x64架构、采用multiboot在qemu中运行的zircon中,建立物理内存管理的过程。

multiboot部分:

从前面的文档中我们可以知道,zircon的启动顺序为GRUB->multiboot->zircon。

在multiboot部分刚开始时,GRUB传入了一个指向multiboot info结构体的指针:

图片 根据这个指针指向的结构体,可以获得最原始的内存信息。multiboot首先对这些信息进行了处理:在add_memory_info函数中,对现有的zbi文件,新建一个名为ZBI_TYPE_E820_TABLE的段,将物理内存分布的信息写入到这个段中。留待zircon内核进行进一步的利用。

图片 multiboot首先从GRUB处得到zbi文件的所在位置,对zbi文件进行解析,检查其中是否有kernel存在,并确定kernel地址。然后解析收集硬件信息,将信息添加到zbi文件中,形成新的item,进入kernel之后,kernel通过分析zbi文件的其他内容,来获取需要的硬件信息,进行进一步初始化。

kernel中的初始化

zircon for x64的kernel既可能经过UEFI启动,也可能有multiboot启动。两种启动方式传入内存信息的方式类似,但解析过程有一点差异。

1.boot_alloc阶段

首先,在刚进入kernel的时候,堆尚未初始化,因此boot过程中使用到的内存分配需要由另一个较为简单的机制来进行。在zircon中采用类似双指针的做法,通过两个地址:boot_alloc_start、boot_alloc_start;来进行内存分配和标记。

这两个地址在start.S中被初始化为整个内核镜像的末地址_end:

图片 这里需要注意的一点是,zircon中为了实现KASLR,将生成的fixup代码直接接到了kernel镜像之后,占用了本该作为bss段的位置,所以在刚进kernel的时候,将fixup代码复制到bss段之后,清空bss段。此时,_end之后是存在fixup代码的,但是这些代码将紧接着被调用,然后成为无用代码。并不妨碍之后这一片内存区域用于boot时期的内存分配。

在初始化完boot_alloc_start和boot_alloc_end之后,可以调用$zx/vm/bootalloc.c和$zx/vm/bootreserve.c中的某些函数来进行内存分配和保留。经过简单注释的代码在github上。

boot alloc时期一直持续到platform_early_init函数被调用之后,在pc_mem_init函数中,将

图片 解析得到的内存信息用于初始化pmm(物理内存管理),然后将之前boot alloc时期分配的内存标记为已用。(boot_serve_wire)

图片 这一调用过程发生在$zx/kernel/platform/pc/memory.cc中,想了解更多细节的话可以查看该文件。

同时,对内存硬件信息的获取是通过上图中的platform_save_bootloader_data函数进行的,主要内容为解析zbi文件,保存对应的信息到bootloader对象中。

pmm_add_arena函数作为第一个被调用的pmm相关函数,起到了初始化的作用。