"这篇实验记录详细描述了MIT JOS LAB3的操作系统实验,作者为华中科技大学集群网络与服务计算实验室的卓达城。实验内容包括环境内存分配、环境空闲链表初始化、env_setup_vm函数实现、segment_alloc函数、以及load_icode函数的详细操作。"
在JOS LAB3实验中,首先进行的是环境内存空间的分配和映射。通过`kmap.cvm_init()`函数分配内存空间,并使用`kmap.cvm_init()`将这些空间映射到物理地址。内存布局由线性地址0x00000000开始,包括KSTACKTOP、KSTKSIZE、UTOP、UPAGES、UVPT、ULIM等区域,直至KERNBASE,然后是UENVS和envs数组,以及bootstack。
接着,实验要求初始化环境空闲链表。在这个过程中,envs[0]被放置在链表头部,以方便后续操作。`env_init`函数被修改以实现这一功能。
`env_setup_vm`函数是实验中的关键部分,它负责为新环境设置页目录。每个新环境都会拥有独立的页目录,并且会将内核的页目录映射到新环境的页目录,使新环境能访问内核。
`segment_alloc`函数用于从给定的虚拟地址`va`开始,分配`len`字节的空间。这个函数在内存管理中起着基础作用,确保每个环境能够有效地管理和使用其内存。
`load_icode`函数是最复杂的部分,它负责加载程序到新环境的虚拟地址。在执行此操作时,需要切换`cr3`寄存器以指向新环境的页目录,加载完成后恢复原值。这个过程基于ELF文件格式,通过程序头表(Program Headers)将不同段的程序加载到正确的位置。ELF文件包含多个段,如.text、.data、.bss等,通过`proghdr`结构体中的信息指导加载。
值得注意的是,在处理BSS段时,代码采取了一种安全的写法,可能是因为BSS段在某些情况下不完全清零。如果改变代码顺序,可能会导致问题。
整个实验详细地展示了操作系统如何为新创建的环境分配内存、设置页目录、分配内存段以及加载程序代码,这些都是操作系统核心功能的基础。通过这样的实践,学生可以深入理解操作系统内部的工作机制。