『操作系统』操作系统实验LAB2附——页表自映射
『操作系统』操作系统实验LAB2附——页表自映射前言笔者在写LAB2时便对该问题不解,拖到LAB4写完才有功夫想起来解决这个问题。在LAB2时,我以为的自映射机制是指页目录的一项映射到他自身,1024个二级页表中有一张是页目录,而把这个“自映射”的前提整个页表在虚拟空间是连续的,且有一个固定的起始虚拟地址值想的理所当然,当然后面我很快发现了这一问题,然而一直想不通究竟如何实现,写LAB3为进程块初始化虚拟空间时,有这么一条语句:
e->env_pgdir[PDX(UVPT)] = PADDR(e->env_pgdir) | PTE_V;
解释说是实现了自映射,可笔者仍不解,为什么单靠一句话就将页表变成“连续”的呢?
特别鸣谢:guo-hy哥哥的博客
虚实转化在我们完成实验所采用的R3000上,软件访存的虚拟地址会先被 MMU 硬件映射到物理地址,随后使用物理地址来访问内存或其他外设。虚实转化这一步是由硬件帮我们进行,页表填充等工作都是OS在辅助进行,硬件只需要知道一个信息即可,即页目录物理地址,在x86架构下存储在CR3寄存器中,在本实验中由于并未涉及硬件,笔者也不是很清楚 ...
『操作系统』操作系统实验LAB6 Challenge
操作系统LAB6挑战性任务实验报告一.实现需求
指导书要求实现的功能:
一行多命令
后台任务操作符 &
引号支持 “”
光标交互的完善,上下左右BACKSPACE功能实现以及协作交互
程序名称 .b 的省略
记录历史命令
更丰富的命令:支持tree; mkdir [-p]; touch [-p]; history
选做一:实现shell环境变量,支持declare [-xr]; unset
选做二:支持相对路径, 支持内部命令cd,pwd
自己额外实现的功能:
追加重定向 >>
转义符 \
支持上级目录 .. , 当前目录 .
更丰富的命令:支持 cp [-r]; mv; rm [-rf]; rmdir [-p]
命令与路径自动补全
上述所有功能皆以 Linux 的行为作为参照,某些地方存在差异。
二. 实现思路1. 一行多命令核心代码如下,同管道机制,令父进程执行右面,子进程执行左面,父进程等待子进程结束后再开始执行。
sh.c:
1234567891011case ';': //依次执行左右两边的指令 if ((r = fork ...
『操作系统』操作系统实验LAB6——管道与Shell
『操作系统』操作系统实验LAB6——管道与Shell一. 思考题Question1. 示例代码中,父进程操作管道的写端,子进程操作管道的读端。如果现在想让父进程作为“读者”,代码应当如何修改?123456789101112case 0: /* 子进程 - 作为管道的写者 */close(fildes[0]); /* 关闭不用的读端 */write(fildes[1], "Hello world\n", 12); /* 向管道中写数据 */close(fildes[1]); /* 写入结束,关闭写端 */exit(EXIT_SUCCESS);default: /* 父进程 - 作为管道的读者 */close(fildes[1]); /* 关闭不用的写端 */read(fildes[0], buf, 100); /* 从管道中读数据 */printf("child-process read:%s",buf); /* 打印读到的数据 */close(fildes[0]); /* 读取结束,关闭读端 */exit(EXIT_SUCCESS);
颠倒一下父 ...
『操作系统』操作系统实验LAB5——文件系统与外存
『操作系统』操作系统实验LAB5——文件系统与外存一. 思考题Question1. 如果通过 kseg0 读写设备,那么对于设备的写入会缓存到 Cache 中。这是一种错误的行为,在实际编写代码的时候这么做会引发不可预知的问题。请思考:这么做会引发什么问题?对于不同种类的设备(如我们提到的串口设备和 IDE 磁盘)的操作会有差异吗?可以从缓存的性质和缓存更新的策略来考虑。当我们与内存交互时使用Cache没有问题,因为内存中的数据只依赖CPU的写操作而改变,使用Cache可以保证访存数据一致性;而当我们与外设交互时,由于外设中的数据的更新并不只依赖于CPU的写操作,还会由外设自己更新(比如计时器的中断位),这会导致出现缓存数据和此刻实际外设数据不一致的情况,即Cache里仍是老数据,而实际的数据外设自身已经更新却无法及时通知给Cache。
有区别,串口是字符设备,只支持顺序读取,无需经过缓存,直接以字符(字节)为单位进行读写;而IDE磁盘是块设备,支持随机读取。内存是磁盘的缓存,如LAB5文件服务进程将磁盘空间映射到进程虚拟空间中,在访问块设备时会经过内存这一层缓存,更高效的对数据进行访 ...
『操作系统』操作系统实验LAB4——系统调用与Fork
『操作系统』操作系统实验LAB4——系统调用与Fork一. 思考题Question1. 思考并回答下面的问题:• 内核在保存现场的时候是如何避免破坏通用寄存器的?• 系统陷入内核调用后可以直接从当时的 $a0-$a3 参数寄存器中得到用户调用 msyscall留下的信息吗?• 我们是怎么做到让 sys 开头的函数“认为”我们提供了和用户调用 msyscall 时同样的参数的?• 内核处理系统调用的过程对 Trapframe 做了哪些更改?这种修改对应的用户态的变化是什么?
(1) 每当发生异常需要进入内核时,OS都会先使用SAVE_ALL将上下文保存进Trapframe中,其中便包括32个通用寄存器,具体来说,首先将指向用户栈的sp赋值给k0,再将32个寄存器及其他保存,最后将sp指向Trapframe的栈顶。在返回用户态时再调用ret_from_exception,首先执行RESTORE_SOME宏将寄存器内容归还,再将k0赋值上EPC,再将sp指向原先的用户栈,最后返回用户态,实现了对通用寄存器(除k0,k1)的保护。
(2) 可以,系统陷入内核后$a0~$a3寄存器没有发生变动 ...
『操作系统』操作系统实验LAB3——进程管理
『操作系统』操作系统实验LAB3——进程管理一. 思考题Question1. 请结合 MOS 中的页目录自映射应用解释代码中 e->env_pgdir[PDX(UVPT)] = PADDR(e->env_pgdir) | PTE_V 的含义。UVPT是kuseg中保存用户(当前进程)页表信息的虚拟内存区,大小为4MB(0x7fc00000-0x80000000),PDX(UVPT)取UVPT前10位,代表着UVPT位于第几个4MB内存区,而e->env_pgdir[PDX(UVPT)]即当前进程的页目录的第PDX(UVPT)项,写入当前页目录的物理地址并置入有效位,意义即完成自映射,当访问UVPT这一虚拟地址时,通过页表转换,可以得到页目录的物理地址。
Question2. elf_load_seg 以函数指针的形式,接受外部自定义的回调函数 map_page。 请你找到与之相关的 data 这一参数在此处的来源,并思考它的作用。没有这个参数可不可以?为什么?data来自kern/env.c的load_icode函数中,他的作用在于传递当前的进程块结构体的指针。我认为 ...
『操作系统』操作系统实验LAB2——内存管理
『操作系统』操作系统实验LAB2——内存管理一. 思考题Question1: 在编写的C程序中,指针变量中存储的地址是虚拟地址,还是物理地址?MIPS 汇编程序中 lw 和 sw 使用的是虚拟地址,还是物理地址?代码在CPU内执行时得到的都是虚拟地址。
Question2: 从可重用性的角度,阐述用宏来实现链表的好处。查看实验环境中的 /usr/include/sys/queue.h,了解其中单向链表与循环链表的实现,比较它们与本实验中使用的双向链表,分析三者在插入与删除操作上的性能差异。用宏实现链表,主要是可以模拟出C语言不具有的泛型功能。因为宏的实现方式是字符串替换,替换时不会考虑到语法等等问题,因此只要给好参数,则任何结构体的链表均能由一组宏统一实现,简单便捷。
插入操作(考虑先寻找,再插入)
双向链表:头部插入O(1),尾部插入O(n),指定节点前O(1),指定节点后O(1)
单向链表:头部插入O(1),尾部插入O(n),指定节点前O(n),指定节点后O(1)
双向循环链表:头部插入O(1),尾部插入O(1),指定节点前O(1,指定节点后O(1)
删除操作:
双向 ...
『操作系统』操作系统实验LAB1——ELF文件,Printk
『操作系统』操作系统实验LAB1——ELF文件,Printk一. 思考题Question1: 请阅读附录中的编译链接详解,尝试分别使用实验环境中的原生x86工具链(gcc、ld、readelf、objdump 等)和MIPS交叉编译工具链(带有 mips-linux-gnu-前缀),重复其中的编译和解析过程,观察相应的结果,并解释其中向 objdump 传入的参数的含义。原生环境是基于x86架构下的,而运用MIPS交叉编译工具则是虚拟了一个MIPS架构环境,编译链接反汇编等建立在MIPS架构下,二者有很大不同。
对于Helloworld文件,下图是用GCC编译后的结果:
下图是使用交叉编译器后的结果:
objdump是反汇编命令,观察LAB1内Makefile的objdump部分,有一些常用的参数如下:
123456objdump [command]-a ## 显示档案库的成员信息,类似ls -l将lib*.a的信息列出。 -l --line-numbers ## 用文件名和行号标注相应的目标代码-d ## 从objfile中反汇编那些特定指令机器码的section。 -D --d ...
『操作系统』操作系统实验LAB0——Linux,Makefile,Bash
『操作系统』操作系统实验LAB0——Git,Linux,Makefile,Bash一. 思考题Question1:Untracked, Staged,Modified如图所示
README.txt文件在未add前,处于未跟踪的状态,在add后,处于暂存区中,即处在staged暂存状态,而在对该文件修改后且未再次add时,该文件处于已修改的状态。一旦初次跟踪该文件(add)后,除非删除该文件,否则将不会再处于未跟踪的状态,若对其进行修改,即使仍需再次add,那也是从已修改状态转移到暂存状态。
Question2:
add the file: git add
stage the file: git add
commit the file: git commit -m
Question3:
git checkout —print.c
git checkout HEAD print.c
git rm —cached hello.txt
Question4:提交三次后版本信息如下图所示:
进行第一次HEAD回退后如下图所示,可见往后回退一个版本到2。
进行一次说明为1的哈希 ...
『智谱清言』Linux裸机配置
『智谱清言』Linux裸机配置裸机只有网络功能,先挂载磁盘至/data。
安装GCC1sudo apt install build-essential
安装Nvidia驱动
查看显卡型号(4位16进制数)
1lspci | grep -i vga
进入网站 https://admin.pci-ids.ucw.cz/read/PC/10de/ ,查询4位16进制数,得到显卡型号
Nvidia官网下载对应版本的驱动(https://www.nvidia.com/en-us/drivers)文件 NVIDIA-Linux-x86_64-550.107.02.run,将文件放进/root目录下
安装驱动 sh /path/to/your/driver,nvidia-smi正常使用即为安装成功
安装CUDA
检查CUDA版本:12.4,查看Linux版本:Ubuntu 22.04.4 LTS
进入网站 https://developer.nvidia.com/cuda-12-4-0-download-archive,找到对应版本的安装包,下载安装(自动重定向到国内源)。
...