OS_lab6_实验报告
1. 思考题想让父进程作为读者,只需要反过来操作就可以了。先关闭写,再进行读操作,最后关闭读并退出即可。代码如下: 123456default: close(fildes[1]); read(fildes[0], buf, 100); printf("father-process read:%s", buf); close(fildes[0]); exit(EXIT_SUCCESS); dup...
OS_lab5_实验报告
1. 思考题 使用kseg0去读写设备,会导致读取的数据可能不正确。因为kseg0段使用cache来访存,当CPU访问一个物理地址时,会先检查该地址所在块是否在cache中,如果在那么直接从cache中进行读或写,如果不在那么申请一块并从内存中读取该块的内容到cache中,并重新访问。这样做之所以可行是因为对cache中的块的数据进行操作等效于对内存直接操作。但是如果外设对内存的操作不会引起cache的变化,如果外设对内存中的数据进行了修改,那么cache中对应块没有随之修改,这就会导致cache中的块的数据和内存中块数据不一致,导致CPU访问的时候读取到了错误的数据。同理CPU的写入也会先写进cache,之后再回写到内存中,这样会导致外设有可能读不到CPU写入的数据。 一个磁盘块的大小是4KB,也就是4096字节;而一个文件控制块FCB的大小固定为256字节,因此一个磁盘块中最多能存储16个文件控制块。一个目录最多拥有1024个磁盘块,因此最多能有16384个文件。我们文件系统支持单个文件最多拥有1024个磁盘块,也就是4MB。 缓冲区的范围是 [DISKMAP,...
OS_lab4_实验报告
1. 思考题 内核在保存现场的时候,通过 SAVE_ALL 宏操作,来将通用寄存器中的值保存在内核栈指针所指向的位置,在异常处理结束时恢复现场,从而防止通用寄存器的值被破坏改变。 可以从当时的 $a0 - $a3 寄存器中得到用户调用 msyscall 时传入的参数。因为在系统调用的时候,这几个寄存器的值不会被改变,因此可以直接获取。 方式就是让sys开头的函数通过正常获取参数的方式,能够获取正确的参数。而这样做的保证是,在用户调用syscall相关函数后,会进行传参,此时会在$a0 - $a3寄存器中保存值,并在用户栈中开辟栈帧,存入相关参数。之后调用msyscall函数,这个函数是个页函数,因此没有栈帧,不会改变栈指针的位置,这个函数直接调用了syscall,陷入了内核态,因此此时 $a0 - $a3...
OS_lab3_实验报告
1. 思考题 首先,MIPS中的虚拟内存结构如下: 因此,base_pgdir中建立了pages和envs的物理地址与虚存中pages和envs的虚拟地址之间的关系,这也同样解释了在map_segment中传入的UPAGES和UENVS的含义,就是pages和envs的虚存首地址。 之后,由于MOS的内核数据共享机制,需要把UTOP以上UVPT以下,即pages和envs的数据暴露给用户空间,因为base_pgdir中已经有分配好的映射关系,因此需要把UTOP到UVPT所对应的页目录项赋值给每个进程的页目录。又由于用户自身的4MB页表放置在UVPT,因此页目录自映射项相对于页目录的偏移即为PDX(UVPT),因此需要把e->env_pgdir[PDX(UVPT)] = PADDR(e->env_pgdir) |...
OS_lab2_实验报告
1. 思考题 在编写的 C 程序中,指针变量中存储的地址被视为虚拟地址,MIPS 汇编程序中 lw 和 sw 指令使用的地址也被视为虚拟地址。CPU访问的都是虚拟地址,通过MMU来转换成对应的物理地址,最后访问内存中的数据。 首先,用宏来处理链表可以化简链表的操作,通过将特定功能的代码封装在宏定义中,可以在实现特定功能时简化操作,增加代码可读性和可维护性。其次,当链表的操作需要修改时,由于该操作会被大量复用,如果逐一修改工作量太大,而用宏则可以只修改宏定义,方便更改。最后,很多种类的链表都包含相似的操作,只要这些链表结构相同,就都可以用这些宏定义来实现相似的操作,只是传入的参数不同,方便了众多链表的使用。 在实验环境中,有单向链表、双向链表、单向队列、双向队列、循环队列。 ...
OS_lab1_实验报告
1. 思考题 首先利用如下简单C语言程序(hello.c)来研究x86工具链和mips工具链的区别 先利用x86工具链编译并反汇编目标文件代码,并观察 12gcc -c hello.c -o hello.oobjdump -DS hello.o > text.txt 最终text.txt内容如下: 再利用mips工具链编译后反汇编: 12mips-linux-gnu-gcc -c hello.c -o hello.omips-linux-gnu-objdump -DS hello.o > text.txt 最终输出如下: 之后再让x86的gcc把hello.c编译成可执行文件,之后再反汇编,代码如下: 12gcc hello.c -o helloobjdump -DS hello > text.txt 结果如下: 可以看到call指令后面填充了 puts@plt,说明在链接的时候这块函数地址被填上了。 再用mips工具链重复以上步骤: 12mips-linux-gnu-gcc hello.c -o...
OS_lab0_实验报告
1. 思考题 ==不一样==。在第一次 git add 之前文件 README.txt 属于未跟踪的文件,此时 git 是无法管理这个文件的,因此 git status 显示未跟踪的文件;而在 git add 并 git commit 之后,git 开始管理这个文件,此时再修改后其状态就会变成已修改未暂存的文件。==其根本原因就是 git 是否管理了这个文件==。如果 git 不管理这个文件,那么这个文件的状态一直都是 untracked ,一旦 git 管理了这个文件,那么经过修改后就会变成 changes not staged for commit ,git add 之后就都是 changes to be committed。 图中,add the file 对应指令 git add,stage the file 对应指令 git add,commit 对应 git commit。 当删除了 print.c 后,可以用 git restore print.c / git...
CPU_P7_design
1. 分析指令集 经过分类,指令共包含R型指令和I型指令 列出其对应的32位机器码,寻找共性差异 R型指令: Type Op Rs Rt Rd Shamt Func 解释 add 000000 (5) (5) (5) 00000 100000 相加(rs+rt->rd) sub 000000 (5) (5) (5) 00000 100010 相减(rs-rt->rd) and 000000 (5) (5) (5) 00000 100100 rs & rt -> rd or 000000 (5) (5) (5) 00000 100101 rs | rt -> rd slt 000000 (5) (5) (5) 00000 101010 rs < rt ? 1 : 0(signed) sltu 000000 (5) (5) (5) 00000 101011 rs < rt ? 1 : 0(unsigned) mfhi 000000 00000 00000 (5) 00000 010000 HI...
CPU_P6_design
1. 分析指令集 经过分类,指令共包含R型指令和I型指令 列出其对应的32位机器码,寻找共性差异 R型指令: Type Op Rs Rt Rd Shamt Func 解释 add 000000 (5) (5) (5) 00000 100000 相加(rs+rt->rd) sub 000000 (5) (5) (5) 00000 100010 相减(rs-rt->rd) and 000000 (5) (5) (5) 00000 100100 rs & rt -> rd or 000000 (5) (5) (5) 00000 100101 rs | rt -> rd slt 000000 (5) (5) (5) 00000 101010 rs < rt ? 1 : 0(signed) sltu 000000 (5) (5) (5) 00000 101011 rs < rt ? 1 : 0(unsigned) mfhi 000000 00000 00000 (5) 00000 010000 HI...
CPU_P5_design
1....