《minix代码解读》word版.doc

上传人:wux****ua 文档编号:9016596 上传时间:2020-04-02 格式:DOC 页数:3 大小:23KB
返回 下载 相关 举报
《minix代码解读》word版.doc_第1页
第1页 / 共3页
《minix代码解读》word版.doc_第2页
第2页 / 共3页
《minix代码解读》word版.doc_第3页
第3页 / 共3页
亲,该文档总共3页,全部预览完了,如果喜欢就下载吧!
资源描述
Minix源码解读报告学号:5100309002姓名:邢佳楠以下是我这学期主要阅读过的minix源码内容,主要从几个比较重点的系统调用的实现入手,阅读的足迹涉及KERNEL、PM、VM、VFS和一点PFS:一、 系统的初始化进程:系统启动后,系统将提示选择多个image中一个进行处理。选择映像后,系统进入pre_init() (kernel/arch/i386/pre_init.c) ,做一些开机准备,之后,完成一些参数的设置,读入相应选择的映像。pre_init() 完成后,进入 mpx.S 中的 kernel_init 下的汇编代码。之后进入main() (kernel/main.c) 函数。在main中:(1) 初始化进程表,标记为空。进程结构 proc 在 kernel/proc.h 中定义。(2) 初始化特权表。亦标记为空。特权表记录了进程对应的能够执行的命令,如能够使用的内存范围,能够使用的 I/O 地址,所使用的信号管理器,能够使用 Kernel_call 的权限等等。关于特权的配置,可以看 include/minix/priv.h 其中的常量(3)初始化boot image所提供的一些默认的进程。按照先后次序一一进行初始化,将他们放进进程表中(复制数据),如果进程是IDLE, CLOCK, SYSTEM,或者根系统进程(即再生服务器),那么他们当前可被调度,否则,初始不应该被调度。对于再生服务器进程,作为系统进程且可以被抢占(这是所有系统服务的共性),另外,设置允许陷入等等。对于其它进程,暂时不允许运行。(4)之后设置堆栈,内存映像,将 proc_ptr 指向当前进程,清除标记,入队,设置为可调度状态,开始调度。(5)初始化中断、System Call数组等等二、 IPC的实现:在上一层,由库函数产生中断进入到kernel 中 (lib/libc/arch/ui386/rts/_ipc.S),具体没看,相关头文件主要是include/minix/ipc.h定义,在这个头文件里定义了 9 种消息类型以及 IPC 函数原型。IPC具体由 do_ipc 函数完成 (kernel/proc.c)。同步的 IPC 由 do_sync_ipc 函数完成,接收的参数有发送者、发送的 flag、接受者、消息内容的指针,异步的IPC由mini_senda 完成(这部分没仔细看)。其中只有RECEIVE 接收 ANY 参数;对于其它如 SEND, SENDREC, NOTIFY 来说,必须指定一个 endpoint 作为对象。使用 isokendpt 检查该 endpoint 是否有效,并将其转换为 process number,如果有效返回 true。检查进程是否有权限执行相应的 call。对于 Kernel Call,只允许 SENDREC。然后执行相应的任务,如 mini_send(), mini_receive(), mini_notify()。mini_send() 首先检查目的进程是否正在处于 block 状态等待这条消息,如果是,则向它复制信息 (caller-p_delivermsg),解锁这个进程;否则,则将发来信息的进程出队,block 它(置 RTS_SENDING 位)同时将这个进程放到目的进程的等待列表中。 mini_receive() 首先检查是否消息队列是否为空且是它想获取的消息,如果是则获取他,解锁caller;否则,再检查是否有异步消息发送(检查 MF_ASYNMSG),否则,block它(置RTS_RECEIVING位)。mini_notify() 首先检查目的进程是否在等待消息,一个进程在执行 SENDREC 系统调用时可同时处于发送和接收状态。如果是则copy该消息,否则,加入到消息位图中(priv结构的s_notify_pending)在block之前要调用deadlock函数检测是否会产生死锁。如果产生死锁,则返回该死锁长度。完成 do_ipc 后,执行 switch_to_user 回到原来部分。三、 Fork()的实现对于系统调用 fork(),用户进程执行 fork() 调用,将会进入到 lib/libc/posix/_fork.c 中定义的 fork(),执行系统调用 _syscall(PM_PROC_NR, FORK, &m),向进程管理器(PM)发送一个消息创建一个新进程,以 sendrec 方式发送。消息传递到 PM 后,PM 执行了 do_fork() 函数 (servers/pm/forkexit.c)。do_fork() 函数检查进程表是否还有空间,接着,查看是否有 mproc 子进程的 slot,如果没有返回错误。接下来,执行 vm_fork(),向 VM 发出消息。转到Servers/vm/fork.c中,VM拷贝一份父进程的 vmproc 信息到子进程的 vmproc 中,分配页表和相应的虚拟地址空间。Minix 默认使用的是独立的 I 和 D 空间,即只需为进程分配其数据段和堆栈段的所需内存,正文段与父进程共享,代码段是不复制的。增加的是全局共享数据和对文件描述符的引用和堆栈。复制内存内容,设置对应的 vm_flags 和 priv 结构体中的 flags,告知 kernel 成功 fork(调用 sys_fork),陷入 Kernel。sys_fork 对应了 kernel/system/do_fork(),首先复制 proc 结构,并使之暂时不能运行,然后去除特权级别,返回。返回后, PM发送异步消息,通知 VFS 进行相应的 fork 操作(servers/vfs/misc.c pm_fork())。如子进程将继承父进程的文件描述符等等。复制 fproc 结构,复制 Root directory 和 Working Directory,返回后,发送一个 SIGSTOP 给子进程。最终返回子进程的 pid。至此,fork 结束。四、 Exec()的实现执行 execvp 后,首先分配空间,获得当前环境变量 $PATH 等,传递适当参数给 execve,并让 execve 最终调用 SYSCALL:_syscall(PM_PROC_NR, EXEC, &m),由 PM 处理系统调用。处理系统调用的函数在 server/pm/exec.c。PM 接收该系统该系统调用后,以 PM_EXEC 的消息类型将请求转发给 VFS。VFS 接收到该消息后,执行 pm_exec。在其中:查看是不是 Super User;通过 fetch_name 函数,从用户空间复制数据(调用 Kernel Call),获得 exec 的文件名;调用 eat_path 打开工作目录或者是根目录。检查文件头是否符合要求,检查文件权限是否可以打开。调用 req_stat 打开文件。调用 read_header 读取文件头结构.读取完成后,分析是否是可执行文件,检查 CPU,检查其 I/D 位。读取文字段、数据段和栈段大小,如果是 I/D 空间非独立的,那么数据段大小应与正文段大小合并。接着执行 exec_newmem 生成一个 exec_newmem 的结构,将结构地址作为消息内容,发送给 PM。PM 接收到后,执行 do_exec_newmem()从 VFS 中复制数据到 PM 本地,再执行 vm_exec_newmem()。vm_exec_newmem 发出 taskcall 到 VM。VM 接收到后,执行 do_exec_newmem(servers/vm/exec.c)。其中计算各段的长度,并检查是否符合要求;调用 new_mem 进行分配新内存和释放旧内存。调用 pt_free 根据原来的页表,对原来的内存进行释放。调用 pt_new 分配新的页表,调用 proc_new 为进程分配内存。复制原来的 vmproc 结构,然后在原来的 slot 上面替换进程。再调用 free_proc 和 clear_proc 清除原来进程的相关内存的信息,比如页表的引用和内存等等。new_mem 完成后,记录下返回的 inode 编号,设备号码和 inode 修改时间。VM 完成工作,回复 PM。此时 PM 接收到回复信息,如果 exec 成功,那么保存 command line、参数等返回,答复 VFS 请求。VFS完成复制等操作后答复 PM。PM 接收到消息后,又执行 exec_restart。看是否执行成功,如果不成功则像它发送 SIGKILL,如果成功,则完善 mproc 结构,初始化信号处理,调用 sys_exec 通知 Kernel exec 完成。Kernel 完成的是复制 command name,设置栈指针和 PC 等,完成后返回 PM。五、 Wait/exit()的实现wait:告知 PM 处于等待某个进程退出的状态,一旦子进程退出或者有父进程不想等待,那么返回。exit: PM接收消息,清除计时器,对父进程计费,发送 SIGHUP 给进程租,告知等待它的进程,同时通知 VFS; VFS 接收到消息后,关闭它打开的文件描述符,清除 fproc 位回复 PM; PM 接收到 VFS 的回复通知 Kernel 完成 exit;Kernel去除中断处理器,释放地址空间,重置 timer,清除 proc 和 priv 结构,答复 PM 已完成; M 接收到 Kernel 的答复,通知 VM,令 VM 清除掉为它非配的内存,以及清除它的 vmproc 结构; VM 答复,PM 清除 mproc 结构,完成六、 Read()的实现:read 库函数被调用后,向 VFS 发出 syscall(READ),VFS 执行 read_write 函数read_write 函数首先验证文件描述符是否有效,并通过文件描述符获取 vnode。如果是 pipe 文件,那么执行 rw_pipe(),如果一个进程从空管道中读,但是写方仍然还存在,那么读的一方挂起;如果写方已经不存在了,那么返回0字节;如果要写一个空管道,但是没进程从这个管道读,返回一个错误(SIGPIPE)。执行 req_readwrite,向 PFS 发出实际的请求; PFS 完成后,更新其访问时间、文件大小等属性;如果是字符设备文件,如果是块设备文件,如果是普通文件,分别发出不同的请求。更新文件大小、修改时间等文件信息,更新 inode 信息;在 VFS 层,更新 vnode 信息;返回。
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 图纸专区 > 大学资料


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!