MIT 6.828 JOS学习笔记16. Lab 2.2
Part 3 Kernel Address Space
JOS把32位线性地址虚拟空间划分成两个部分。其中用户环境(进程运行环境)通常占据低地址的那部分,叫用户地址空间。而操作系统内核总是占据高地址的部分,叫内核地址空间。这两个部分的分界线是定义在memlayout.h文件中的一个宏 ULIM。JOS为内核保留了接近256MB的虚拟地址空间。这就可以理解了,为什么在实验1中要给操作系统设计一个高地址的地址空间。如果不这样做,用户环境的地址空间就不够了。
Permission and Fault Isolation
由于内核和用户进程只能访问各自的地址空间,所以我们必须在x86页表中使用访问权限位(Permission Bits)来使用户进程的代码只能访问用户地址空间,而不是内核地址空间。否则用户代码中的一些错误可能会覆写内核中的数据,最终导致内核的崩溃。
处在用户地址空间中的代码不能访问高于ULIM的地址空间,但是内核可以读写这部分空间。而内核和用户对于地址范围[UTOP, ULIM]有着相同的访问权限,那就是可以读取但是不可以写入。这一个部分的地址空间通常被用于把一些只读的内核数据结构暴露给用户地址空间的代码。在UTOP之下的地址范围是给用户进程使用的,用户进程可以访问,修改这部分地址空间的内容。
Initializing the Kernel Address Space
现在我们要设置一下UTOP之上的地址空间:这也是整个虚拟地址空间中的内核地址空间部分。inc/memlayout.h文件中已经向你展示了这部分地址空间的布局。你可以使用你刚刚编写的函数来设置这些地址的布局。
Exercise 5
继续完善mem_init()函数,你的程序现在必须能够通过check_kern_pgdir()和check_page_installed_pgdir()函数的检测。
答:
剩下的工作就是要完善mem_init()函数,现在要完善的功能就是把关于操作系统的一些重要的地址范围映射到现在的新页目录项上kern_pgdir上。这里我们可以利用前面定义过的boot_map_region函数。
首先我们要映射的范围是把pages数组映射到线性地址UPAGES,大小为一个PTSIZE。
所以我们添加的代码是:
boot_map_region(kern_pgdir, UPAGES, PTSIZE, PADDR(pages), PTE_U);
其中perm变量之所以设置为PTE_U,是因为这部分空间是kernel space和user space中的代码都能访问的,所以要设置PTE_U。
然后映射内核的堆栈区域,把由bootstack变量所标记的物理地址范围映射给内核的堆栈。内核堆栈的虚拟地址范围是[KSTACKTOP-PTSIZE, KSTACKTOP),不过要把这个范围划分成两部分:
* [KSTACKTOP-KSTKSIZE, KSTACKTOP) 这部分映射关系加入的页表中。
* [KSTACKTOP-PTSIZE, KSTACKTOP-KSTKSIZE) 这部分不进行映射。
对这部分地址的访问权限是,kernel space 可以读写,user space 无权访问,所以代码如下:
boot_map_region(kern_pgdir, KSTACKTOP - KSTKSIZE, KSTKSIZE, PADDR(bootstack), PTE_W)
最后映射整个操作系统内核,虚拟地址范围是[KERNBASE, 2^32],物理地址范围是[0,2^32 - KERNBASE]。
访问权限是,kernel space 可以读写,user space 无权访问,所以代码如下:
boot_map_region(kern_pgdir, KERNBASE, 0xffffffff - KERNBASE, , PTE_W);
至此,Exercise 5已经全部完成。
Question:
2. 到目前为止页目录表中已经包含多少有效页目录项?他们都映射到哪里?
3BD号页目录项,指向的是kern_pgdir
3BC号页目录项,指向的是pages数组
3BF号页目录项,指向的是bootstack
3C0~3FF号页目录项,指向的是kernel
3. 如果我们把kernel和user environment放在一个相同的地址空间中。为什么用户程序不同读取,写入内核的内存空间?用什么机制保护内核的地址范围。
用户程序不能去随意修改内核中的代码,数据,否则可能会破坏内核,造成程序崩溃。
正常的操作系统通常采用两个部件来完成对内核地址的保护,一个是通过段机制来实现的,但是JOS中的分段功能并没有实现。二就是通过分页机制来实现,通过把页表项中的 Supervisor/User位置0,那么用户态的代码就不能访问内存中的这个页。
4. 这个操作系统的可以支持的最大数量的物理内存是多大?
由于这个操作系统利用一个大小为4MB的空间UPAGES来存放所有的页的PageInfo结构体信息,每个结构体的大小为8B,所以一共可以存放512K个PageInfo结构体,所以一共可以出现512K个物理页,每个物理页大小为4KB,自然总的物理内存占2GB。
5. 如果现在的物理内存页达到最大个数,那么管理这些内存所需要的额外空间开销有多少?
这里不太明白,参考别的答案是,首先需要存放所有的PageInfo,需要4MB,需要存放页目录表,kern_pgdir,4KB,还需要存放当前的页表,大小为2MB。所以总的开销就是6MB + 4KB。
6. 回顾entry.S文件中,当分页机制开启时,寄存器EIP的值仍旧是一个小的值。在哪个位置代码才开始运行在高于KERNBASE的虚拟地址空间中的?当程序位于开启分页之后到运行在KERNBASE之上这之间的时候,EIP的值是小的值,怎么保证可以把这个值转换为真实物理地址的?
在entry.S文件中有一个指令 jmp *%eax,这个指令要完成跳转,就会重新设置EIP的值,把它设置为寄存器eax中的值,而这个值是大于KERNBASE的,所以就完成了EIP从小的值到大于KERNBASE的值的转换。
在entry_pgdir这个页表中,也把虚拟地址空间[0, 4MB)映射到物理地址空间[0, 4MB)上,所以当访问位于[0, 4MB)之间的虚拟地址时,可以把它们转换为物理地址。
Address Space Layout Alternatives
进程的虚拟地址空间的布局不是只有我们讨论的这种唯一的情况,我们也可以把内核映射到低地址处。但是JOS之所以要这么做,是为了保证x86的向后兼容性。
只要我们能够仔细设计,虽然很难,但是我们也能设计出来一种内核的布局方式,使得进程的地址空间就是从0到4GB,无需为内核预留一部分空间,但是仍然能够保证,用户进程不会破坏操作系统的指令,数据。
至此,lab 2已经全部完成~欢迎大家的意见与问题
zzqwf12345@163.com
MIT 6.828 JOS学习笔记16. Lab 2.2的更多相关文章
- MIT 6.828 JOS学习笔记2. Lab 1 Part 1.2: PC bootstrap
Lab 1 Part 1: PC bootstrap 我们继续~ PC机的物理地址空间 这一节我们将深入的探究到底PC是如何启动的.首先我们看一下通常一个PC的物理地址空间是如何布局的: ...
- MIT 6.828 JOS学习笔记15. Lab 2.1
Lab 2: Memory Management lab2中多出来的几个文件: inc/memlayout.h kern/pmap.c kern/pmap.h kern/kclock.h kern/k ...
- MIT 6.828 JOS学习笔记10. Lab 1 Part 3: The kernel
Lab 1 Part 3: The kernel 现在我们将开始具体讨论一下JOS内核了.就像boot loader一样,内核开始的时候也是一些汇编语句,用于设置一些东西,来保证C语言的程序能够正确的 ...
- MIT 6.828 JOS学习笔记7. Lab 1 Part 2.2: The Boot Loader
Lab 1 Part 2 The Boot Loader Loading the Kernel 我们现在可以进一步的讨论一下boot loader中的C语言的部分,即boot/main.c.但是在我们 ...
- MIT 6.828 JOS学习笔记1. Lab 1 Part 1: PC Bootstrap
Lab 1: Booting a PC Part 1: PC Bootstrap 介绍这一部分知识的目的就是让你能够更加熟悉x86汇编语言,以及PC启动的整个过程,而且也会首次学习使用QEMU软件来仿 ...
- MIT 6.828 JOS学习笔记18. Lab 3.2 Part B: Page Faults, Breakpoints Exceptions, and System Calls
现在你的操作系统内核已经具备一定的异常处理能力了,在这部分实验中,我们将会进一步完善它,使它能够处理不同类型的中断/异常. Handling Page Fault 缺页中断是一个非常重要的中断,因为我 ...
- MIT 6.828 JOS学习笔记17. Lab 3.1 Part A User Environments
Introduction 在这个实验中,我们将实现操作系统的一些基本功能,来实现用户环境下的进程的正常运行.你将会加强JOS内核的功能,为它增添一些重要的数据结构,用来记录用户进程环境的一些信息:创建 ...
- MIT 6.828 JOS学习笔记4. Lab 1 Part 2.1: The Boot Loader
Part 2: The Boot Loader 对于PC来说,软盘,硬盘都可以被划分为一个个大小为512字节的区域,叫做扇区.一个扇区是一次磁盘操作的最小粒度.每一次读取或者写入操作都必须是一个或多个 ...
- MIT 6.828 JOS学习笔记0. 写在前面的话
0. 简介 操作系统是计算机科学中十分重要的一门基础学科,是一名计算机专业毕业生必须要具备的基础知识.但是在学习这门课时,如果仅仅把目光停留在课本上一些关于操作系统概念上的叙述,并不能对操作系统有着深 ...
随机推荐
- RabbitMQ修改端口号和心跳时间
定读者正在Windows系列的操纵体系中装置好了Rabbit MQ后,请找到装置途径下的etc文件夹下,将rabbitmq.config.example备份一份,并点窜为config范例的文件,即为] ...
- 学习实战java虚拟机的计划图
啥也不说了,实战java虚拟机,好好学习,天天向上! <实战java虚拟机>一书Q交流群:397196583
- CSS3使用Font Awesome字体图标的控件样例(按钮,工具栏,输入框)
按钮上加入font awesome图标,用原生的input button标签无法实现,查看网上的只能通过<a><li></li></a>实现此功能,通过 ...
- Java与各种数据库连接代码
6.MySQL数据库Class.forName("org.gjt.mm.mysql.Driver").newInstance();String url ="jdbc:my ...
- Apache commons-configuration setDelimiterParsingDisable不生效的处理
Apache commons-configuration setDelimiterParsingDisable不生效的处理 项目中有用到commons-configuration,版本1.9. 配置初 ...
- shell脚本重新挂载出问题的卷
#!/bin/bash#卷的全路径示例#pathexample =mount -t cetusfs 127.0.0.1:/cinderv/var/lib/cinder/volumes/0f6a20f4 ...
- JS打开新页面跳转
有时候使用js进行页面跳转,想使用 a 标签中 target="_blank" 形式,跳转打开一个新的页面. 可以使用以下脚本,创建一个 a标签,然后模拟点击操作. 代码如下: ...
- Http原理理解及内容整理
更多资料及交流请加群:
- [PHP][REDIS]phpredis 'RedisException' with message 'read error on connection'
最近一个后台常驻job通过redis的brpop阻塞读取消息时,设置了永不超时 while( $re=$redis->brPop($queue_name,0) ){ } 但是在实际的使用中发现很 ...
- JS学习进阶中 come on!
1,定义新的属性来扩展对象 新方法:defineProperty() 实例: var data = {}: Object.defineProperty(data,"type",{ ...