MIT6.828 Lab2: 第2部分 Virtual Memory

Virtual, Linear, and Physical Addresses
  在x86体系中,虚拟地址(Virtual Address)是由两部分组成,一个是段选择子(segment selector),另一个是段内偏移(segment offset)。线性地址(Linear Address)指的是通过段地址转换机构把虚拟地址进行转换之后得到的地址。物理地址(Physical Addresses)是分页地址转换机构把线性地址进行转换之后得到的真实的内存地址,这个地址将会最终送到你的内存芯片的地址总线上。
这里写图片描述

  我们所编写的C语言程序中的指针的值是虚拟地址中段内偏移部分的值。在boot/boot.S文件中,我们引入了一个全局描述符表,这个表通过把所有段的基址设置为0,界限设置为0xffffffff的方式,关闭了分段管理的功能。因此虚拟地址中的段选择子字段的内容已经没有任何意义,线性地址的值总是等于虚拟地址中段内偏移的值。
  回顾一下lab1中的part 3,我们引入了一个简单的页表,使得内核可以运行与0xf0100000的虚拟地址空间,尽管它所在的真实位置是物理地址0x00100000处,刚刚好在ROM BIOS之上。这个页表仅仅映射了4MB的内存空间。在我们这个JOS操作系统中,我们希望把这种映射扩展到物理内存的头256MB空间上,并且把这部分物理空间映射到从0xf0000000开始的虚拟空间中,以及一些其他的虚拟地址空间中。

  Exercise3:
  通过GDB,我们只能通过虚拟地址来查看内存所存放的内容,但是如果我们能够访问物理内存的话,肯定会更有帮助的。我们可以看一下QEMU中的一些常用指令,特别是xp指令,可以允许我们去访问物理内存地址。

  “QEMU中有一个内置的监控器(moniter),首先通过在运行着QEMU软件的terminal里面输入 ctrl-a c,可以让我们切换到这个监控器。” 这个是官方给出的做法,但是我是通过xshell远程连接,貌似快捷键冲突,没有响应的。后来发现在lab目录下面输入如下指令,一样可以打开moniter:

  qemu-system-i386 -hda obj/kern/kernel.img -monitor stdio -gdb tcp::26000 -D qemu.log

  打开monitor后,就可以输入如下比较常见的指令:

  xp/Nx paddr – 查看paddr物理地址处开始的,N个字的16进制的表示结果。

  info registers – 展示所有内部寄存器的状态。

  info mem – 展示所有已经被页表映射的虚拟地址空间,以及它们的访问优先级。

  info pg – 展示当前页表的结构。(我这版本的qemu没有该指令)

  在之后的实验中,你将会经常遇到一种情况,多个不同的虚拟地址被同时映射到相同的物理页上面。这时我们需要记录一下每一个物理页上存在着多少不同的虚拟地址来引用它,这个值存放在这个物理页的PageInfo结构体的pp_ref成员变量中。当这个值变为0时,这个物理页才可以被释放。通常来说,任意一个物理页p的pp_ref值等于它在所有的页表项中,被位于虚拟地址UTOP之下的虚拟页所映射的次数(UTOP之上的地址范围在启动的时候已经被映射完成了,之后不会被改动)。

  当我们使用page_alloc函数的时

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实验概述 本次实验是MIT 6.828操作系统课程的第一次实验,主要内容是编写一个简单的操作系统内核,并在QEMU虚拟机上运行。本次实验共有9个练习,其中练习9要求实现一个简单的用户程序并运行。 练习9要求我们实现一个简单的用户程序,该程序能够在屏幕上输出一些信息,并等待用户输入,输入结束后将输入内容输出到屏幕上。用户程序的具体要求如下: - 输出一些信息,例如“Hello World!”。 - 等待用户输入,可以使用getchar()函数实现。 - 将用户输入内容输出到屏幕上。 实验过程 1. 编写用户程序 我们首先在lab1目录下创建一个user文件夹,用于存放用户程序。然后创建一个名为“test.c”的文件,编写用户程序的代码如下: ``` #include <stdio.h> int main() { printf("Hello World!\n"); char c = getchar(); printf("You entered: %c\n", c); return 0; } ``` 这段代码的功能是输出“Hello World!”并等待用户输入,输入结束后将输入内容输出到屏幕上。 2. 修改Makefile文件 为了能够编译用户程序,我们需要修改Makefile文件。具体修改如下: ``` UPROGS=\ _cat\ _echo\ _forktest\ _grep\ _init\ _kill\ _ln\ _ls\ _mkdir\ _rm\ _sh\ _stressfs\ _usertests\ _wc\ _test\ # 添加用户程序的名称 $(OBJDIR)/_test: $(OBJDIR)/test.o $(LIBDIR)/ulib.o | $(OBJDIR) $(LD) $(LDFLAGS) -N -e main -Ttext 0 -o $@ $^ $(OBJDIR)/test.o: test.c | $(OBJDIR) $(CC) $(CFLAGS) -c -o $@ $< ``` 在UPROGS变量中添加上刚刚编写的用户程序的名称“_test”,然后在Makefile文件的末尾添加如上代码。 3. 编译内核和用户程序 在终端运行命令“make”,编译内核和用户程序。 4. 运行QEMU虚拟机 在终端运行命令“make qemu”,启动QEMU虚拟机。 5. 运行用户程序 在QEMU虚拟机中,输入“test”,即可运行刚刚编写的用户程序。运行结果如下: ``` Hello World! This is a test. You entered: T ``` 可以看到,程序首先输出了“Hello World!”这个信息,然后等待用户输入。我们输入了“This is a test.”这个字符串,然后按下回车键,程序将输入内容输出到了屏幕上。 实验总结 本次实验要求我们实现一个简单的用户程序并运行。通过编写代码、修改Makefile文件、编译内核和用户程序、启动虚拟机以及运行用户程序等步骤,我们成功地完成了本次实验,并学会了如何在操作系统内核中运行用户程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值