文件系统

文件系统是建立在硬盘上的一个程序,所以由2部分组成:驱动和管理文件系统的进程FS。

首先看一下驱动是如何工作的:

通常,主板上面有2个IDE插槽,分别叫做IDE0/IDE1。每个IDE通道又可以接2个设备。驱动进程的目的就是要隐藏硬件细节,向FS进程提供统一的接口具体到这里,驱动为FS提供的接口就是打开,读取,写入,关闭等接口。下面是硬盘驱动程序:

Task_hd()

{

Recv(any, msg) //接受任何进程传来的消息

If(msg == DEV_OPEN)  //如果是打开设备消息,则对硬盘寄存器做一些操作,比如获取硬盘信息等。

{

Out_byte(***)   //向硬盘寄存器写入数据

Recv(interrupt, msg) //阻塞等待硬盘中断发生(表示需要的数据已经得到)

}

Send(src, msg) //将获取的硬盘信息返回给发送者进程

}

上面的程序之添加了一个读取硬盘信息的消息,其他比如读取写入数据的消息和这个都是类似的。

有一点需要注意,驱动程序task_hd在读取硬盘信息或者写入数据到硬盘时候的操作其实比上面的情况略微复杂,下面来看一个完成的调用过程:

1 task_fs 文件系统进程 需要操作硬盘,给硬盘驱动进程task_hd() 发送一个msg。

2 假设这时,task_hd()处于空闲状态,即等待在recv(any,msg)处,则会接受这个消息,并向硬盘发送命令。

3 硬盘完成工作后,会触发中断, Recv(interrupt, msg)返回,并给task_fs 文件系统进程发送硬盘数据消息。

4 task_fs 文件系统进程 得到CPU时间时,会收到硬盘数据消息。

最简单的硬盘驱动看来是告一段落了。下面就可以在此基础上实现一个文件系统,首先需要明白一个文件系统的几个基本要素

1)  有地方存放metadata(一般为硬盘第二个扇区,因为第一个扇区为引导分区)

2)  有地方记录扇区使用情况(位图法)

3)  有地方记录任一文件信息,包括文件名,修改时间,占用哪些扇区等(一个i-node数组,每个元素包含了文件名,属性等信息。同时也需要一个位图来表示i-node数组的使用情况)

4)  文件索引

以后就按照这个方法来组织硬盘结构,创建/删除/写入/读取文件不过是按照这种格式来组织硬盘而已

为了实现多系统在硬盘上共存,必须将硬盘划分为多个分区。每个系统占用一个分区。通过一个硬盘的引导扇区可以设置硬盘分区,硬盘最多可以分为4个物理分区。其中每个分区还可以继续划分为多个逻辑分区。

一般Linux的设备分为主设备号和次设备号,主设备号表示不同的物理设备(硬盘,软盘);次设备号表示物理设备上的分区。归纳一下就是:主设备号告诉OS用哪个驱动程序来处理,次设备号告诉驱动程序这是哪个设备。

下面看一下硬盘驱动读取和写入数据的过程:

1 首先还是一样task_fs() 文件系统进程通过前面实现的IPC机制将读取(写入)硬盘数据消息发送(即复制)给task_hd()

2 task_hd()

{

Case:DEV_OPEN //如果某用户进程需要打开一个文件

为文件内容分配扇区

分配一个i-node

分配inode-map

分配sector-map

创建文件索引

Case: DEV_READ //读文件

首先找到将要读取的文件的文件描述符和位置

根据文件描述符通过驱动获取的该文件在硬盘的具体位置(即i-node)。

将硬盘内容复制到缓存

}

这一部分写的不是很清楚,理一下思路,我的理解就是硬盘首先有一个文件系统结构(fat32,ntfs,ext2等等),相对于的就有一个硬盘驱动程序用来管理硬盘使用的文件系统并对上层提供文件操作的接口。上层用户需要读取硬盘数据的时候,首先将消息发送给FS,然后FS会将该消息发送给硬盘驱动程序,硬盘驱动程序根据硬盘所使用的文件格式来找到相应的数据并吧数据复制到OS提供的一个缓存中拱用户进程使用。

内存管理

到了现在,还没有完成了就是和内存相关的一些东西,首先看看如何创建一个进程(fork),每个shell就是一个子进程。

一个新的进程需要的条件有:

1 代码,数据,堆栈(从父进程复制过来)

2 在进程表中占据一个位置

3 在GDT中有一个位置,指向了该进程对应的LTD,也就是指向了进程的数据和堆栈等

看一下linux中fork用法:

First_proc()

{

Int id = fork();

If(pid != 0) //这是父进程

Else 子进程运行

}

父子进程公用一个代码段

可以看到,内存管理主要需要在OS中增加2个进程,分别为所有用户的祖先进程(INIT0)和MM进程(memory Management process)。

Init0进程有些特殊,首先一般的进程的虚拟内存空间对用户来说是0-4GB,但是init0的内存在这里大致等于内核占用内存的大小。

Fork的大概步骤如下:

1 用户调用fork

2 通过消息机制发送FORK消息给MM

3 MM主循环完成创建进程的工作,主要流程为:找一个空闲的进程表项作为新进程的进程表项;读取父进程的表示内存占用的LDT,从中取出父进程的代码,数据和堆栈段内存首地址和范围。

3 根据父进程的内存占用情况,分配相同大小的内存给子进程。(分配内存需要注意的就是内存不要重复使用),然后将父进程的内存中的内容复制给子进程。

4 如果父进程有打开文件,要给FS进程发送一个消息来处理父子进程间的共享文件。(FS利用计数器实现)

销毁一个进程也差不多,唯一需要注意的就是MM在销毁一个进程的时候,需要首先销毁他的所有子进程。

接下来说明一下几个概念,大多是复制过来的:

CRT:一个应用程序只能调用2种东西:属于自己的函数,以及中断(系统调用就是软中断)。但是实际上,OS还为普通应用程序提供了一个CRT,这个库里面有已经编译好的库函数代码。用户应用程序可以很方便的使用CRT,而免去了很多中断调用。

OS自带应用程序:每个OS都可以附带和安装很多应用程序,简单来说目的就是为了把应用程序从光盘中安装到OS认识的硬盘中并知道位置,这样在需要用时,OS可以自己找到该应用程序。例如,一个最简单的应用程序:

_start

Main(){printf(***);}

把他安装到OS中的步骤大致如下:

1 编译连接该应用程序并打包(设为inst.tar)

2 将打包的应用程序二进制文件写入OS安装盘的某扇区(设该扇区号为X)。

3 启动系统时,在mkfs()创建文件系统时建立一个新的文件cmd.tar,他对应的起始文件扇区号为X。

4 在init进程中,将cmd.tar解压,将其中包含的文件(即为inst.tar)存入文件系统。

Exec才等同于windows里面的CreartProcess.

First_proc()

{

Int id = fork();

If(pid != 0) //这是父进程

Else 子进程运行

{

Exec()   //参数即为新的代码段

}

}

Exec的执行流程:

检查参数个数并将它们依次存放到某连续内存处

向MM发送消息,消息体就是上面存放参数的连续内存。

3 MM消息接收到这个消息,将参数取出(由于exec所在进程和MM不是同一个进程,所有他们的虚拟地址不一样,MM需要通过物理地址复制的方式来获取消息)

根据exec传来的参数,MM将要执行文件复制到自己的缓冲区中

被执行文件是elf格式,MM根据格式将被执行文件的各个段放置到合适的空闲内存中。

建立栈

 

 

OK all done with simplest mode.. 

              2011.1.15 AM8:45  

        i love joliet - teddy_xiong  in ZNUFE

sylar MAIL: cug@live.cn

转载于:https://www.cnblogs.com/xumaojun/p/8544130.html

一个操作系统的实现(3)相关推荐

  1. 《一个操作系统的实现》读书笔记连载ing……

    从昨天起深陷<一个操作系统的实现>这个书不能自拔,这本书可以说再次燃起了我小时候想写操作系统的美好愿望,所以说愿望总是美好的,还进入了大学开始真正去学计算机才发现似乎写操作系统是和我没什么 ...

  2. 一个操作系统的实现(1)

    一个操作系统的实现 说明:本文是一个简单的学习记录,不是全面给大家提供学习的文章,文章内容均代表作者的个人观点,难免会有错误.转载请保留作者信息. 2010/11/20                ...

  3. 《Orange’s 一个操作系统的实现》3.保护模式3----DOS加载.EXE过程

    在<<Orange's 一个操作系统的实现>>一书中有时使用了org 0100h,为何是0100h?因为书中的例子是为了突破引导扇区512字节的限制, 而将asm文件编译为.c ...

  4. 《Orange’s 一个操作系统的实现》3.保护模式7-特权级转移(通过调用门转移目标段-无特权级转换)...

    在上次的代码基础上,添加一个代码段作为通过调用门转移的目标段.了解一下调用的工作方法,代码分析如下: <<红色标识部分为新增代码>> ; =================== ...

  5. 一个操作系统的实现01

    老师说,写好操作系统,期末就没有大作业了 没有大作业=期末空闲时间更多=我可以看每到期末就看的停不下来的电视剧 欢迎大家来和我一起来学操作系统制作 参考书籍: 一个操作系统的实现 于渊 参考博客:ht ...

  6. orange's系统可以装mysql 吗?_bochs 2.4.2 ubuntu 安装运行问题《orange#39;s 一个操作系统的...

    用源码安装完后会遇到的问题: <1> 运行可能碰到如下问题: Event type: PANIC Device: [ ] Message: dlopen failed for module ...

  7. Orange's:一个操作系统的实现 Descriptor 3宏详解

    补充:关于GDT/LDT.段选择子和段描述符的解释       GDT/LDT:GDT/LDT是段描述符表,里面定义了每个段的段描述符的界限和属性,而段描述符的基址是在代码段中初始化的.        ...

  8. Orange‘s’ 一个操作系统的实现

    突然想要随时记录一下实验过程中的各种问题,因此有了此文档: 由于是中途开始的,所以就偷懒直接跳过了vm.ubuntu32位16.04.bochs2.6.8.nasm的安装,下面开始正文内容: 2022 ...

  9. <一个操作系统的实现>:sudo mount -o loop pm.img /mnt/floppy出错

    在<一个操作系统的实现>中使用命令sudo mount -o loop pm.img /mnt/floppy出现如下错误: mount: /mnt/floppy: wrong fs typ ...

  10. 一个操作系统的实现:BOOT

    参考书籍为<一个64位操作系统的设计与实现>.<30天自制操作系统> Boot的作用主要是当BIOS将执行权交给boot后,初始化文件系统,然后寻找Loader文件,如果找到则 ...

最新文章

  1. Codeforces Round #417:E. FountainsSagheer and Apple Tree(树上博弈)
  2. Makefile语法基础介绍
  3. R语言文摘:Subsetting Data
  4. 【iOS数据持久化】Plist使用
  5. Visual Studio附加到进程调试
  6. Python用selenium简单方法处理完子窗口切换到主窗口
  7. 【R语言-20行代码】牛顿迭代法求伽马函数极大似然估计法的参数估计
  8. 【网络】解决‘ipconfig不是内部或外部命令,也不是可运行的程序
  9. 剑指offer:31-32记录(4道)
  10. k8s包管理器helm_是时候使用Helm了:Helm, Kubernetes的包管理工具
  11. 一个对iBatis的总结写的不错(转载)
  12. Linux操作系统中的IP配置
  13. 基于范德蒙矩阵的Erasure code技术详解
  14. 共享文件夹没有权限访问
  15. ASO关键词排名优化如何操作联想词,aso 联想词 工具
  16. excel 柱状图 多个水滴图组合
  17. 查理芒格思维模型 —— 费马帕斯卡系统
  18. ZZNUOJ_用C语言编写程序实现1236:数的逆转(附完整源码)
  19. oracle 10g与oracle 11g的不同
  20. AI生成的灌篮高手真人版,爷青回

热门文章

  1. 七月算法--12月机器学习在线班-第五次课笔记—回归
  2. 实验3 --俄罗斯方块 with 20135335郝爽
  3. uva 10716 Evil Straw Warts Live
  4. 修改、读取txt文档
  5. MOSS服务器场迁移1-有关切换登录用户时需要刷新一次才能成功的问题
  6. 李洋疯狂C语言之合法帧
  7. 如果备份还原SecureCRT、Xshell远程工具远程
  8. [UWP]了解模板化控件(4):TemplatePart
  9. 李开复评价马斯克:他真正的目的是把人变成半机械人
  10. vue新手入门——vue-cli搭建