一、目的

熟悉 Minix 操作系统的进程管理
学习 Unix 风格的内存管理

二、内容与设计思想

修改Minix3.1.2a的进程管理器,改进brk系统调用的实现,使得分配给进程的数据段+栈段空间耗尽时,brk系统调用给该进程 分配一个更大的内存空间,并将原来空间中的 数据复制至新分 配的内存空间,释放原来的内存空间,并通知内核映射新分配的内存段。

三、使用环境

Minix,Moba

四、实验过程

1、完成安装minix3.1.2系统并配置相关设置。
要先编译Minix再修改内核。

2、PM是用户进程,printf结果显示在虚拟机下,可以不需要串口输出。
相关的函数
alloc_mem 分配内存
sys_abscopy 拷贝内存内容
free_mem 释放内存
sys_newmap 通知内核,注册内存段
用户调用brk函数针对的是虚拟地址,而minix最底层内存管理是物理地址,不能混淆。
需要小心处理clicks 和 bytes的单位换算和对齐。

3、修改/usr/src/servers/pm/alloc.c 中的 alloc_mem 函数,把 first-fit 修改成 best-fit,即分配 内存之前,先遍历整个空闲内存块列表,找到最小最佳匹配的空闲块。

PUBLIC phys_clicks alloc_mem(clicks)
phys_clicks clicks;     /* amount of memory requested */
{register struct hole *hp, *prev_ptr, *best, *prev_best;phys_clicks old_base;int flag=0;do {prev_ptr = NIL_HOLE;hp = hole_head;while (hp != NIL_HOLE && hp->h_base < swap_base) //遍历空闲链表{if(hp->h_len >= clicks && ((hp->h_len < best->h_len)||(flag==0)))//当找到合适的空闲块时,先让best等于这个比他大的块,当找到更小的则替换。{best=hp;prev_best=prev_ptr;flag=1;}prev_ptr = hp;hp = hp->h_next;}} while (swap_out());     /* try to swap some other process out */if (flag==1) //能找到{old_base = best->h_base; //记录块的起始位置best->h_base += clicks;    //best起始位置发生了变化,等于其实位置加分配的clicks大小。best->h_len -= clicks;    块的大小等于原长度-被分配的长度/* Remember new high watermark of used memory. */if(best->h_base > high_watermark)high_watermark = best->h_base;/* Delete the hole if used up completely. */if (best->h_len == 0) del_slot(prev_best, best);/* Return the start address of the acquired block. */return(old_base);} return(NO_MEM);
}

4、修改/usr/src/servers/pm/break.c中的adjust函数,并增加了一个allocate_new_mem局部函数在adjust函数中调用。brk系统调用流程:
do_brk函数计算数据段新的边界,然后调用adjust函数,adjust函数计算程序当前的空闲空间是否足够分配:
(1)若足够,则调整数据段指针,堆栈指针;通知内核程序的映像发生了变化,返回do_brk函数。
(2)若不够,调用allocate_new_mem函数申请新的足够大的内存空间;将程序现有的数据段贺堆栈段的内容分别拷贝至新内存区域的底部(bottom)和顶部(top);通知内核程序的映像发生了变化;返回do_brk函数。

if (lower < gap_base) {/* data and stack collided */if (allocate_new_mem(rmp,(phys_clicks)(mem_sp->mem_vir+mem_sp->mem_len-mem_dp->mem_vir)) == 0)  return(ENOMEM);
}
/*=======================================================**               allocate_new_mem                     *
*=======================================================*/
PUBLIC int allocate_new_mem(rmp,clicks)
register struct mproc *rmp;
phys_clicks clicks;
{ /* local variables declarations */register struct mem_map *mem_sp,*mem_dp; /* stack and data structs */phys_bytes old_bytes,data_bytes,stak_bytes,old_d_abs,new_d_abs,old_s_abs,new_s_abs; /* used to transform between bytes and clicks */phys_clicks old_clicks,old_base,new_clicks,new_base; /* used to transform the old click to a new one */phys_clicks data_clicks,new_s_base,old_s_base,stak_clicks; /* used to transform the old stack or data to a new one */int error; /* used to receive error code *//* allocation of new memory */mem_dp = &rmp->mp_seg[D]; /* get data struct */mem_sp = &rmp->mp_seg[S]; /* get stack struct */old_clicks = clicks; /* old size */new_clicks = clicks*2; /* new size */if ((new_base = alloc_mem(new_clicks))==NO_MEM) return (0);  /* get new_base pointer *//* copy data from original source */old_base = rmp->mp_seg[D].mem_phys;  /* get old_base address */old_s_base = rmp->mp_seg[S].mem_phys;  /* get old_stack_base address */new_s_base = new_base + new_clicks - mem_sp->mem_len;  /* get new_stack_base address */new_d_abs = (phys_bytes) new_base << CLICK_SHIFT;  /* new data address */old_d_abs = (phys_bytes) old_base << CLICK_SHIFT;  /* old data address */new_s_abs = (phys_bytes) new_s_base << CLICK_SHIFT;  /* new stack address */data_bytes = (phys_bytes) rmp->mp_seg[D].mem_len << CLICK_SHIFT;  /* data size (bytes) */stak_bytes = (phys_bytes) rmp->mp_seg[S].mem_len << CLICK_SHIFT;  /* stack size (bytes) */if ((error=sys_memset(0,new_d_abs,(new_clicks<<CLICK_SHIFT)))!=OK){ /* get a new empty space */panic(__FILE__,"new mem can't be zero",error); } error = sys_abscopy(old_d_abs,new_d_abs,data_bytes);  /* copy data from old memory allocation */if (error < 0 ) panic(__FILE__,"allocate_new_mem can't copy",error); /* error handler  */error = sys_abscopy(old_s_abs,new_s_abs,stak_bytes); /* copy stack from old memory allocation */if (error < 0 ) panic(__FILE__,"allocate_new_mem can't copy",error); /* error handler *//* change pointer to fit the current allocation */rmp->mp_seg[D].mem_phys = new_base;  /* change data address to new_base */rmp->mp_seg[S].mem_phys = new_s_base;  /* change data address to new stack base */rmp->mp_seg[S].mem_vir = mem_dp->mem_vir + new_clicks - mem_sp->mem_len; /* change stack memory address to click-len */free_mem(old_base,old_clicks); /* free old_base altogether */return (1);
}

5、(1)进入/usr/src/servers目录,输入make image, 等编译成功之后输入make install 安装新的PM程 序。
(2)进入/usr/src/tools目录,输入make hdboot, 成功之后再键入make install命令安装新的内核程 序。
(3)键入shutdown 命令关闭虚拟机,进入boot monitor界面。设置启动新内核的选项,在提示符键入:newminix(5,start new kernel) {image=/boot/image/3.1.2ar1;boot;}
(4)然后回车,键入save命令保存设置。
(5)为启动菜单中的选择内核版本的键(数字键,可选其 他数字键),3.1.2ar1为在/usr/src/tools目录中输入make install 之后生成的内核版本号,请记 得在/usr/src/tools中执行make install命令之后记录生成的新内核版本号。 5. 输入menu命令,然后敲数字键(上一步骤中设置的数字)启动新内核,登录进minix 3中测试。

但因为我先修改了内核再编译的minix,就出现了问题:

但事已至此,我先尝试用编译好的test1和test2文件直接运行也没有成功,然后我又尝试使用chmod +x ./test1赋予权限,终于成功了。

# ./test1
incremented by 1, total 1
incremented by 2, total 3
incremented by 4, total 7
incremented by 8, total 15
incremented by 16, total 31
incremented by 32, total 63
incremented by 64, total 127
incremented by 128, total 255
incremented by 256, total 511
incremented by 512, total 1023
incremented by 1024, total 2047
incremented by 2048, total 4095
incremented by 4096, total 8191
incremented by 8192, total 16383
incremented by 16384, total 32767
incremented by 32768, total 65535
incremented by 65536, total 131071
incremented by 131072, total 262143
incremented by 262144, total 524287
incremented by 524288, total 1048575
incremented by 1048576, total 2097151
incremented by 2097152, total 4194303
incremented by 4194304, total 8388607
incremented by 8388608, total 16777215
incremented by 16777216, total 33554431
incremented by 33554432, total 67108863
# ./test2
incremented by: 1, total: 1 , result: 760
incremented by: 2, total: 3 , result: 4096
incremented by: 4, total: 7 , result: 4098
incremented by: 8, total: 15 , result: 4102
incremented by: 16, total: 31 , result: 4110
incremented by: 32, total: 63 , result: 4126
incremented by: 64, total: 127 , result: 4158
incremented by: 128, total: 255 , result: 4222
incremented by: 256, total: 511 , result: 4350
incremented by: 512, total: 1023 , result: 4606
incremented by: 1024, total: 2047 , result: 5118
incremented by: 2048, total: 4095 , result: 6142
incremented by: 4096, total: 8191 , result: 8190
incremented by: 8192, total: 16383 , result: 12286
incremented by: 16384, total: 32767 , result: 20478
incremented by: 32768, total: 65535 , result: 36862
incremented by: 65536, total: 131071 , result: 69630
incremented by: 131072, total: 262143 , result: 135166
incremented by: 262144, total: 524287 , result: 266238
incremented by: 524288, total: 1048575 , result: 528382
incremented by: 1048576, total: 2097151 , result: 1052670
incremented by: 2097152, total: 4194303 , result: 2101246
incremented by: 4194304, total: 8388607 , result: 4198398
incremented by: 8388608, total: 16777215 , result: 8392702
incremented by: 16777216, total: 33554431 , result: 16781310
incremented by: 33554432, total: 67108863 , result: 3355852

熟悉Minix3.1.2a操作系统的进程管理相关推荐

  1. Linux操作系统的进程管理详解

    Linux操作系统的进程管理详解 pkill & pgrep pkill & pgrep 是两个很方便的命令.省去了要先ps auwx | grep xxxx然后再根据pid kill ...

  2. 如何保证进程间同步工作_系统设计硬核知识(2)——操作系统的进程管理

    操作系统基本原理包含以下 5 大管理. 我们先来说说进程管理. 因为处理机是计算机系统的核心资源,所以整个操作系统的重心是处理机管理. 处理机管理中最基本的.最重要的概念是进程.进程是系统并发执行的体 ...

  3. 《操作系统》实验报告——熟悉Linux基础命令及进程管理

    理论知识 Linux--进程管理 Linux--Linux C语言编程基础知识 手把手教你安装Linux虚拟机 一.实验目的 (1)加深对进程概念的理解,明确进程和程序的区别. (2)进一步认识并发执 ...

  4. 操作系统——实验壹——熟悉Linux基础命令及进程管理

    一. 实验目的 加深对进程概念的理解,明确进程和程序的区别. 进一步认识并发执行的实质. 分析进程争用资源的现象,学习解决进程互斥的方法. 二. 实验内容 运行程序,查看自己运行的结果,并进行分析. ...

  5. 现代操作系统及进程管理(思维导图)

    本人最近学习了现代操作系统的进程管理,现将笔记(思维导图形式)整理如下: 1.从资源管理角度看操作系统,包含以下功能: 2.进程的管理是操作系统一项重要的功能 3.在多道程序设计中,内存中有多个进程. ...

  6. 操作系统实验报告——实验一:熟悉Linux命令及进程管理

    实验目的 熟悉Linux系统,掌握Linux系统的登入.退出等操作: 熟悉Linux命令及进程管理.作业控制: 学会使用Linux下C语言编程的基本知识: 掌握Linux中vi的基本操作: 掌握Lin ...

  7. 【知识强化】第二章 进程管理 2.1 进程与线程

    处理机管理相关的内容.认识一个很重要的概念叫做进程. 系统当中正在运行的程序怎么怎么地,怎么怎么地,偶尔也会提到进程这个术语."进程"和"程序"这两个概念是比较 ...

  8. Linux—进程管理

    1. 进程的概念 Linux是一个多用户多任务的操作系统.多用户是指多个用户可以在同一时间使用同一个linux系统:多任务是指在Linux下可以同时执行多个任务,更详细的说,linux采用了分时管理的 ...

  9. linux进程管理 pdf,高效与精细的结合--Linux的进程管理.pdf

    高效与精细的结合--Linux的进程管理.pdf 第 卷 第 期 A 文献标识码 I T6L 76 28 L J6 7 8 676 LJ Q Q656 8J6 6 82 K 797863 R28J 2 ...

最新文章

  1. python123程序设计题说句心里话_用c++写一个简单的计算器程序
  2. 【Matlab 控制】构建系统,绘制零极点
  3. 【Q】之Linux中的防火墙netfilter iptables
  4. Code Review的重要性
  5. Java压缩技术(三) ZIP解压缩——Java原生实现
  6. 内部收益率irr_介绍一个神器,内部收益率IRR
  7. Retroifit原理
  8. Spring 类管理机制
  9. Android学习笔记(八)
  10. java用 拼接字符串的原理_Java String 拼接字符串原理详解
  11. 约束布局管理器 CAConstraintLayoutManager 以及其不起作用
  12. 哈哈哈,第一次做codeforce
  13. 数据库索引失效的一些场景
  14. 拼命成为有能力为自己老年生活买单的人|独秀日记
  15. win10 x64+VS2017社区版+OpenCV3.2.0安装
  16. 计算机网络长度,以太网中mtu默认长度 你应该知道的计算机网络知识(2)
  17. java 字符串不等于_java中字符串不等于怎么判断
  18. 清空input的type为file时的值
  19. Statistical Analysis:关联度分析之灰色关联分析软件
  20. 数据结构算法题:回文数的实现

热门文章

  1. 《水浒传》读后(2) 鲁智深
  2. 人脸检测之Faceboxes
  3. python+opencv 实现图像人脸检测及视频中的人脸检测
  4. keil护眼色配置及插件整理
  5. 【操作系统】经典PV操作题目
  6. ionic4使用QR Scanner插件实现二维码、条形码扫描功能
  7. videojs简单使用
  8. 如何获取bssid_路由器Bssid如何获取?
  9. 怒刷排列组合,如何解“排列组合”一类的问题
  10. 新手入门,webpack入门详细教程