本次需要完成的内容:
(1)用 Bochs 调试工具跟踪 Linux 0.11 的地址翻译(地址映射)过程,了解 IA-32 和 Linux 0.11 的内存管理机制;
(2)在 Ubuntu 上编写多进程的生产者—消费者程序,用共享内存做缓冲区;
(3)在信号量实验的基础上,为 Linux 0.11 增加共享内存功能,并将生产者—消费者程序移植到 Linux 0.11。
挂载hdc 编写test.c
挂载hdc文件系统,然后在usr/root目录内增加test.c文件用于测试地址映射
调试Linux-0.11 输入./dbg-asm用汇编级调试启动linux-0.11 然后输入以下命令编译并运行test.c gcc -o test test.c ./test
此时需要让Linux-0.11的test跳出死循环,所以需要找到逻辑地址ds:0X00003004对应的物理地址,将它的内容更改为0。 在终端中输入sreg,得到gdtr的基址值为0x00005cb8,ldtr为0x0068即0000 0000 0110 1000 b,可知索引为1101b即13,TI位为0,即GDT中的第13项为LDT的段描述符。此时会进入在test.c内的while死循环,然后ctrl+c暂停bochs。
输入xp /2w 0x00005cb8+13 * 8得到LDT段描述符,可以得到LDT的基址为0x00f9a2d0 ds段选择子为0x0017 => 0000 0000 0001 0111 b,可知索引为10b即2,TI位为1,即LDT中的第2项为ds的段描述符,输入xp/2w 0x00f9a2d0+2*8得到ds段描述符,可以知道ds的基址为0x10000000,所以0x3004对应的线性地址为0x10000000+0x3004=0x10003004
输入xp /w 644获取页目录项,可知页表基地址为0x00fa6000。 输入xp /w 0x00fa6000+34得到物理基址为0xfa5000。 输入xp /w 0xfa5000+4得到的内容即test.c中的变量的值,输入setpmem 0xfa5004 4 0将它设为0。 在终端中输入c让bochs继续运行,发现test跳出循环。
在unistd.h中增加下面的代码:
然后增加两个系统调用 修改sys.h文件,在此文件中增加函数声明
在system_call.s中把nr_system_calls改为78(系统调用个数)
接下来在kernel下添加shm.c
编写消费者和生产者程序 gcc 运行bochs,输入: gcc -o pro producer.c gcc -o con consumer.c 编译这两个程序, 然后输入 pro > proOutput & con > conOutput & 来同时运行这两个程序,并将结果保存到proOutput和conOutput中。 最后输入sync。
实验心得
经过此次试验,我初步了解操作系统的段页式内存管理系统,理解了段表、页表、逻辑地址、线性地址、物理地址等一系列的概念。
学习时间 114分钟
操作时间 92分钟
按键次数 1564次
实验次数 6次
报告字数 2331字
是否完成 完成