Lab 2: Part1~2

Lab 2

Introduction

在本实验中,您将为您的操作系统编写内存管理代码。内存管理有两个组件。
第一个组件是内核的物理内存分配器,这样内核可以分配内存,然后释放它。你的分配器将以4096字节(称为页)为单位进行操作。您的任务将是维护数据结构,这些数据结构记录了哪些物理页面是空闲的,哪些被分配了,以及有多少进程共享每个分配的页面。您还将编写用于分配和释放内存页的例程。

Getting started

一顿git操作:首先在lab1分支 git pull,然后创建一个lab2分支,再合并lab1,lab2分支。(我好像操作反了,合并了再pull,lab1分支没有pull到,可能少几个文件,我在lab2分支上做实验应该没影响吧)

lab2分支pull了之后会发现多了几个文件

  • inc/memlayout.h
  • kern/pmap.c
  • kern/pmap.h
  • kern/kclock.h
  • kern/kclock.c

memlayout describes the layout of the virtual address space that you must implement by modifying pmap.(Memlayout描述了必须通过修改pmap来实现的虚拟地址空间的布局), memlayout and pmap define the PageInfo structure that you'll use to keep track of(跟踪) which pages of physical memory(物理内存页面) are free.

要特别注意memlayout.h和pmap.h,因为本实验要求您使用和理解它们所包含的许多定义。您可能还想回顾一下inc/mmu.h,因为它还包含了一些对本实验室有用的定义。

Lab Requirements

好像是mit的作业要求,不关我事。

Hand-In Procedure

好像也是作业要求,关于git提交的,不管。

Part 1: Physical Page Management

The operating system must keep track of(跟踪) which parts of physical RAM are free and which are currently in use. JOS manages the PC's physical memory with page granularity(JOS以页为单位管理物理内存) so that it can use the MMU to map(映射) and protect each piece(每个) of allocated(已分配) memory.

You'll now write the physical page allocator(分配器). It keeps track of(跟踪) which pages are free with a linked list of struct PageInfo objects(通过一个结构PageInfo对象的链表来跟踪哪些页面是空闲的) (which, unlike xv6, are not embedded in the free pages themselves(与v6不同的是,这些对象并没有嵌入到空闲页面本身中)), each corresponding to a physical page(每个struct PageInfo objects对应一个物理页). You need to write the physical page allocator before you can write the rest of the virtual memory implementation, because your page table management code will need to allocate physical memory in which to store page tables.(在编写虚拟内存实现的其余部分之前,您需要编写物理页分配器,因为page table management code 将需要分配用于存储page tables的物理内存。)

已在Exercise 1 实现:https://i.cnblogs.com/articles

Part 2: Virtual Memory

Before doing anything else, familiarize(熟悉) yourself with the x86's protected-mode memory management architecture(架构): namely(即) segmentation(分段) and page translation.(页转换)

Exercise 2

A C pointer is the "offset" component of the virtual address.
In boot/boot.S, we installed a Global Descriptor Table (GDT) that effectively disabled(有效地极禁用了) segment translation by setting all segment base addresses to 0 and limits to 0xffffffff.
Hence(因此) the "selector" has no effect and the linear address always equals the offset of the virtual address.(因为段翻译被仅用了,所以linear address = virtual address)
In lab 3, we'll have to interact(交互) a little more with segmentation to set up privilege levels(特权等级), but as for memory translation, we can ignore segmentation throughout(全部,整个) the JOS labs and focus solely(仅仅) on page translation.

Recall(回想) that in part 3 of lab 1, we installed a simple page table(页表) so that the kernel could run at its link address of 0xf0100000, even though it is actually loaded in physical memory just above the ROM BIOS at 0x00100000.
This page table mapped only 4MB of memory. In the virtual address space layout you are going to set up for JOS in this lab, we'll expand this to map the first 256MB of physical memory starting at virtual address 0xf0000000 and to map a number of other regions of the virtual address space.

在 boot/boot.S 我们设置了一个GDT,变相的禁用了段翻译,使得虚拟地址(LOGICAL ADDRESS)经过转换后仍然等于线性地址。
在lab 1 part 3 中,我们设置了一个简单的 page table, 将 将范围从0xf0000000到0xf0400000的线性地址地址转换为物理地址0x00000000到0x00400000,通过这样,kernel 可以运行在 0xf0100000 的线性地址上,实际运行在 0x00100000 的物理地址上。

Exercise3

从在CPU上执行的代码开始,一旦我们进入了保护模式(首先要进入boot/boot.S),就无法直接使用 linear or physical address.
所有内存引用都被解释为虚拟地址并被MMU转换,这意味着C中的所有指针都是虚拟地址。

The JOS kernel often needs to manipulate(操作) addresses as opaque(不透明的) values or as integers, without dereferencing(解除指针引用) them, for example in the physical memory allocator.
Sometimes these are virtual addresses, and sometimes they are physical addresses.
To help document(记录) the code, the JOS source distinguishes(区分) the two cases:the type uintptr_t represents(代表) opaque virtual addresses,and physaddr_t represents physical addresses.
Both these types are really just synonyms(同义词) for 32-bit integers (uint32_t), so the compiler won't stop you from assigning(分配0 one type to another! Since they are integer types (not pointers), the compiler will complain if you try to dereference(废弃) them.

JOS内核可以通过将uintptr_t转换为指针类型来解引用它。相反,内核不能合理地解除对物理地址的引用,因为MMU会转换所有的内存引用。如果将physaddr_t转换为指针并解除引用,您可能能够加载并存储到结果地址(硬件将其解释为一个虚拟地址),但您可能无法获得您想要的内存位置

C type	Address type
T*  	Virtual
uintptr_t  	Virtual
physaddr_t  	Physical

Question
1.Assuming(假设) that the following JOS kernel code is correct, what type should variable x have, uintptr_t or physaddr_t?

mystery_t x;
	char* value = return_a_pointer();
	*value = 10;
	x = (mystery_t) value;

答:physaddr_t

The JOS kernel sometimes needs to read or modify memory for which it knows only the physical address.
For example, adding a mapping to a page table may require allocating physical memory to store a page directory and then initializing that memory.
However, the kernel cannot bypass(绕过) virtual address translation and thus cannot directly load and store to physical addresses.
One reason JOS remaps(重新映射) all of physical memory starting from physical address 0 at virtual address 0xf0000000 is to help the kernel read and write memory for which it knows just the physical address.
In order to translate a physical address into a virtual address that the kernel can actually read and write, the kernel must add 0xf0000000 to the physical address to find its corresponding virtual address in the remapped region(区域). You should use KADDR(pa) to do that addition(加法).

The JOS kernel also sometimes needs to be able to find a physical address given the virtual address of the memory in which a kernel data structure is stored.
Kernel global variables and memory allocated by boot_alloc() are in the region where the kernel was loaded, starting at 0xf0000000, the very region where we mapped all of physical memory. Thus, to turn a virtual address in this region into a physical address, the kernel can simply subtract(减去) 0xf0000000. You should use PADDR(va) to do that subtraction(减法).

Reference counting

Now you'll write a set of routines(例程) to manage page tables: to insert and remove linear-to-physical mappings, and to create page table pages when needed.

Exercise 4

Part 3: Kernel Address Space

另起一篇:part3

posted @ 2021-12-23 16:52  Pril  阅读(59)  评论(0)    收藏  举报