格斯文档网

您现在的位置是:格斯文档网 > 心得体会 >

中原工学院操作系统实验报告

 计算机操作系统实验报告 专

 业:

 网络工程

  班

 级:

 162 班

 学

 号:

  学生姓名:

  指导教师:

  2019/06/06 目 录 实验一

 进程控制

 ................................ .............................

 3 3 一、实验目的: ............................................................ 3 二、实验平台: ............................................................ 4 三、实验内容: ............................................................ 4 实验结果 ................................................................. 5 单线程执行结果: .......................................................... 7 实验总结 ................................................................. 8 实验二

 进程同步

 ................................ .............................

 8 8 一、实验目的: ............................................................ 8 二、实验平台: ............................................................ 8 三、实验内容: ............................................................ 9 执行结果 ................................................................ 12 实验总结 ................................................................ 12 实验三

 添加内核模块

 ................................ ........................

 12 一、实验目的: ........................................................... 12 二、实验平台: ........................................................... 13 三、实验内容: ........................................................... 13 readprocess、c 代码: .................................................... 14 Makefile 代码: .......................................................... 15 processinfo 文件源代码: ................................................. 17 Makefile 文件源代码: .................................................... 18 实验总结 ................................................................ 20 实验四

 统计操作系统缺页次数

 ................................ ................

 20 实验目的 ................................................................ 20 实验内容 ................................................................ 21 实验过程 ................................................................ 21 1、 修改内核源代码,添加统计变量 ......................................... 21

 2、 配置编译新内核 ...................................................... 23 3、 编译内核与模块 ...................................................... 24 4、 安装新内核模块与新内核 .............................................. 24 5、 编写读取 pfcount 值的模块代码 ........................................ 25 6、编译、构建内核模块 ................................................... 26 7、加载模块到内核中 ..................................................... 26 实验总结 ................................................................ 27 实验五

 4 EXT4 文件系统结构分析

 ................................ ...............

 27 一、实验目的: ........................................................... 27 二、实验平台: ........................................................... 27 三、实验内容: ........................................................... 27 实验总结 ................................................................ 31 实验一 进程控制 一、实验目的: 加深对进程概念的理解,明确进程与程序的区别;掌握 Linux 操作系统的进程创建与终止操作,体会父进程与子进程的关系及进程状态的变化;进一步认识并发执行的实质,编写并发程序。

 二、实验平台: 虚拟机:VMWare9 以上 操作系统:Ubuntu12、04 以上 编辑器:Gedit | Vim 编译器:Gcc 三、实验内容: (1)编写一段程序,使用系统调用 fork()创建两个子进程,当此程序运行时,在系统中有一个父进程与两个子进程活动。让每一个进程在屏幕上显示“身份信息”:父进程显示“Parent process! PID=xxx1 PPID=xxx2”;子进程显示“Childx process! PID=xxx PPID=xxx”。多运行几次,观察记录屏幕上的显示结果,并分析原因。

 说明: xxx1 为进程号,用 getpid()函数可获取进程号; xxx2 为父进程号,用 getppid()函数可获取父进程号;

 Childx 中 x 为 1 与 2,用来区别两个子进程; wait()函数用来避免父进程在子进程终止之前终止。

 程序源码: #include<stdio、h> #include<unistd、h> #include<stdlib、h> #define NUM 2 int main(void) {

  pid_t pid1,pid2;

  if((pid1=fork())<0){

  printf("创建进程 1 失败");

  }else{

 if(pid1==0){

 //子进程 1 执行

 printf("Child1

 process: ");

 printf("PID=%d

 PPID=%d \n",getpid(),getppid());

  sleep(2);

 }else{

 if((pid2=fork())<0){

 printf("创建进程 2 失败");

  }else{

 if(pid2==0){

 //子进程 2 执行

 printf("Child2

 process: ");

 printf("PID=%d

 PPID=%d \n",getpid(),getppid());

  }

 else{

 //父进程执行

  wait();

 wait();

  printf("Parent process: ");

  printf("PID=%d

 PPID=%d \n",getpid(),getppid());

  exit(0);

 }

  }

 }

  } } 实验结果 whtcmiss@whtcmiss-VirtualBox:~/Desktop$ gcc test1、c -o test whtcmiss@whtcmiss-VirtualBox:~/Desktop$ 、/test Child2

 process: PID=2527

 PPID=2525

 Child1

 process: PID=2526

 PPID=2525

 Parent process: PID=2525

 PPID=2127

 whtcmiss@whtcmiss-VirtualBox:~/Desktop$ 、/test Child2

 process: PID=2530

 PPID=2528

 Child1

 process: PID=2529

 PPID=2528

 Parent process: PID=2528

 PPID=2127

 whtcmiss@whtcmiss-VirtualBox:~/Desktop$ 、/test Child2

 process: PID=2533

 PPID=2531

 Child1

 process: PID=2532

 PPID=2531

 Parent process: PID=2531

 PPID=2127 实验结果分析: 第一次程序运行结果,两个子进程的 PPID 都就是 2525,就是由同一个进程创建。而父进程 PID 就是 2525,父进程 PPID 就是 2127,说明父进程也就是一系统进程的子进程。

 第二次程序运行结果,父进程 PID 就是 2528,PPID 就是 2127,说明父进程就是由同一进程创建的,父进程也就是以子进程的方式存在,且进程 ID 就是逐渐递增的。

 (2)fork()与exec()系列函数能同时运行多个程序,利用上述函数将下面单进程顺序执行的程序single、c改造成可并发执行3个进程的程序multi_process、c;并用time命令获取程序的执行时间,比较单进程与多进程运行时间,并分析原因。

  //single、c #include <stdio、h>

 #define NUM 5

 int main(void)

 {

 void print_msg(char *m);

 print_msg("Good ");

 print_msg("Morning

 ");

 print_msg("2\n");

  return 0;

 }

 void print_msg(char *m)

 {

 int i;

 for(i = 0; i<NUM; i++){

 printf("%s",m);

 fflush(stdout);

 sleep(1); } } 编译运行方法: #gcc single、c –o single #time 、/single 单线程执行结果 :

 多线程代码: #multi_process、c #include <stdio、h> #include<unistd、h> #include<stdlib、h> #define NUM 5 int main(void)

 {

  pid_t pid[3];

  int i;

  for(i=1;i<=3;i++){

 pid[i-1]=fork();

 if(pid[i-1]==0||pid[i-1]==-1)

  break;

  }

 if(pid[0]==0){

 execl("print","print","Good",NULL);

 }

  else {

  if(pid[1]==0){

  execl("print","print","Hello",NULL);

  }

 else{

 if(pid[2]==0){

  execl("print","print","2",NULL);

 }

 wait();

  wait();

  wait();

  exit(0);

  }

  }

 return 0; }

  实验分析:第二个实验结果,第二个程序的多线程因为就是并发执行,而且就是有三个线程,所以在时间上几乎就是单线程的 1/3,而且因为就是并发的,所以打印结果就是无序的。

 实验总结 本次实验首先要明确 进程与程序的区别,我通过在 Linux 操作系统的进程创建与终止操作,运行父进程与子进程,查瞧运行结果与进程状态的变化。实验过程中也了解了父进程与子进程的运行过程及其机制。

 实验二 进程同步 一、实验目的: 掌握基本的同步算法,理解经典进程同步问题的本质;学习使用 Linux 的进程同步机制,掌握相关 API 的使用方法;能利用信号量机制,采用多种同步算法实现不会发生死锁的哲学家进餐程序。

 二、实验平台: 虚拟机:VMWare9 以上 操作系统:Ubuntu12、04 以上

 编辑器:Gedit | Vim 编译器:Gcc 三、实验内容: (1)以哲学家进餐模型为依据,在 Linux 控制台环境下创建 5 个进程,用 semget 函数创建一个信号量集(5 个信号量,初值为 1),模拟哲学家的思考与进餐行为:每一位哲学家饥饿时,先拿起左手筷子,再拿起右手筷子;筷子就是临界资源,为每一支筷子定义 1 个互斥信号量;想拿到筷子需要先对信号量做 P 操作,使用完释放筷子对信号量做 V 操作。

 伪代码描述: semaphore chopstick[5]={1,1,1,1,1}; • 第 i 位哲学家的活动可描述为:

  do{

  printf("%d is thinking\n",i);

  printf("%d is hungry\n",i);

  wait(chopstick[i]);

  //拿左筷子

  wait(chopstick[(i+1) % 5]);

 //拿右筷子

 printf("%d is eating\n",i);

  signal(chopstick[i]);

 //放左筷子

 signal(chopstick[(i+1) % 5]);

 //放右筷子

 …

 }while[true];

 运行该组进程,观察进程就是否能一直运行下去,若停滞则发生了什么现象?并分析原因。

 实验结果: 源码如下: #include <stdio、h> #include <stdlib、h> #include <string、h> #include <stdint、h> #include <stdbool、h> #include <errno、h> #include <unistd、h> #include <sys/types、h> #include <sys/stat、h> #include <sys/ipc、h> #include <sys/sem、h> #include <sys/wait、h> union semun {

 int val; struct semid_ds *buf; unsigned short *array; struct seminfo *_buf; }; #define ERR_EXIT(m) \ do { \ perror(m); \ exit(EXIT_FAILURE); \ } while(0) //获取互斥信号量 void wait_mutex(int mutex) { struct sembuf sb={0,-1,0}; semop(mutex,&sb,1);//对互斥信号量进行操作 } //取得筷子 void wait_v(int semid,int num) { struct sembuf sb={num,-1,0}; semop(semid,&sb,1); } //释放筷子 void signal_p(int semid,int num) { struct sembuf sb={num,1,0}; semop(semid,&sb,1); } //释放互斥变量 mutex void signal_mutex(int semid0) { struct sembuf sb={0,1,0}; semop(semid0,&sb,1); } //ph 函数 void ph(int num,int semid,int semid0) { int left=num; int right=(num+1)%5; for(;;) { printf("%d is thinking\n",num); sleep(1); printf("%d is hungry\n",num);

 sleep(1); //wait 操作,控制哲学家最多 4 人能进餐 wait_mutex(semid0); wait_v(semid,left); wait_v(semid,right); printf("%d is eating\n",num); sleep(1); //signal 操作 signal_p(semid,right);//释放右筷子 signal_p(semid,left);//释放左快子 signal_mutex(semid0);//释放互斥信号量 } } int main(int argc,char *argv[]) { int semid,semid0; //创建两个信号量集 semid0=semget(IPC_PRIVATE,1,IPC_CREAT | 0666); semid=semget(IPC_PRIVATE,5,IPC_CREAT | 0666); // union semun su; su、val=1; int i; for(i=0;i<5;i++) { //semctl()系统调用在一个信号量集(或集合中的单个信号量)上执行各种控制操作 semctl(semid,i,SETVAL,su); } //设定 semid0 信号量的初始值 union semun su0; su0、val=4; semctl(semid0,0,SETVAL,su0); //创建 4 个子进程 int num=0; pid_t pid; for(i=1;i<5;i++) { pid=fork(); if(pid<0) {ERR_EXIT("fork");} if(pid==0) {num=i;break;} } //第 num 个哲学家要做的事 ph(num,semid,semid0); return 0;

 } 执行结果

 实验总结

  哲学家进餐的问题就是操作系统信号量同步的经典例题了。这次我通过解决哲学家进餐的哲学问题从而对进程同步有一个更好的理解,解决这个问题书中给出了三种解决方法。我在实验中也就是用这三种方法去定义信号量解决死锁问题。通过信号量的获取与 wait 操作去控制进餐就是通过互斥信号量的获取,若没有信号量便不能执行,而且只有四个哲学家能同时进餐也避免了死锁的出现。

 实验三 添加内核模块 一、实验目的: 学习 Linux 模块的基本概念与原理,学习内核模块编程的基本技术,利用内核模块编程访问进程描述符,操作内核的基本数据结构,加深对进程的理解;理解 proc 文件系统的作用,学习proc 文件的创建方法,掌握这种用户态与核心态通信的方法。

 二、实验平台: 虚拟机:VMWare9 操作系统:Ubuntu12、04 编辑器:Gedit | Vi 三、实验内容: (1)阅读内核模块实例 hello、c,掌握内核模块的主要构成;阅读 Makefile 文件,理解内核模块的编译方法及执行过程;掌握模块安装、卸载,以及查瞧模块信息的方法。

 将 hello、o 与 Makefile 文件放在一个文件夹 workspace 中,使用 make 命令使其生成了 hello、ko 等文件,如图:

 使用命令载入模块,如图:

 使用命令显示载入系统的模块,如图:

 使用 dmesg 命令查瞧系统的内核模块信息如图:

  使用 sudo rmmod hello 命令卸载该模块:

 (2)设计一个模块,功能就是列出系统中所有内核进程的程序名、PID 号与进程状态。主要步骤: 阅读内核源代码,了解进程描述符 task_struct 中与本实验有关的成员项,以及访问进程队列的宏 for_each_process; 编写 readprocess 模块,获取进程信息; 修改 Makefile 文件,编译、安装模块,查瞧输出信息; 查瞧模块信息,卸载模块。

 源代码如下: readprocess 、c 代码: #include<linux/init、h>

 #include<linux/module、h>

 #include<linux/sched、h>

 #include<linux/list、h>

  MODULE_LICENSE("GPL");

 static int mod_init_readprocess(void);

 static void mod_exit_readprocess(void); module_init(mod_init_readprocess);

 module_exit(mod_exit_readprocess);

 int mod_init_readprocess(void)

 {

  printk(KERN_INFO"-------start-------\n");

 struct task_struct *p;

  printk("display moudleinfo is :\n");

  for_each_process(p)

  {

 printk("NAME:%s\t\t PID:%d\t\t STATE:%ld\t\t\n",p->comm,p->pid,p->state);

 }

  return 0;

 }

 void mod_exit_readprocess(void)

 {

 printk(KERN_INFO"--------end--------\n");

 } Makefile 代码: ifneq ($(KERNELRELEASE),)

 obj-m:=readprocess、o else

 KDIR:= /lib/modules/$(shell uname -r)/build

 PWD:= $(shell pwd) default:

 $(MAKE) -C $(KDIR) M=$(PWD) modules clean:

 $(MAKE) -C $(KDIR) M=$(PWD) clean Endif 将 process、c 与 Makefile 文件放在同一个文件夹下使用 make 函数生成后缀为、ko 文件:

  使用命令载入模块,如图:

 使用 lsmod 命令显示载入系统的模块,如图:

 使用 dmesg 命令查瞧到系统的内核模块信息 ,如图:

  使用 sudo rrmod hello 命令卸载该模块,如图:

 (3)利用内核模块编程,在/proc 目录下用自己的学号创建一个目录,如/proc/2 然后在学号目录下创建一个processinfo文件,如/proc/2/processinfo,此文件为只读文件,用于显示所有内核进程的程序名、PID 号与进程状态。主要步骤: 修改(2)中 readprocess 模块,在模块初始化函数中创建目录及 proc 文件,并定义产生 proc文件内容的函数(获取进程信息);在卸载模块函数中删除相应的 proc 文件及目录; 修改 Makefile 文件,编译、安装模块; 执行 cat /proc/2/processinfo 命令,查瞧进程信息。

 processinfo 文件源代码: #include<linux/init、h> #include<linux/module、h> #include<linux/sched、h> #include<linux/list、h> #include<linux/proc_fs、h> MODULE_LICENSE("GPL"); static int mod_init_readprocess(void); static void mod_exit_readprocess(void); module_init(mod_init_readprocess); module_exit(mod_exit_readprocess); struct proc_dir_entry *feeyu_dir,*processinfo_file; int processinfo_read_procmem(char *page,char **start,off_t offset,int count,int *eof,void *data); int mod_init_readprocess(void)

 {

 printk(KERN_INFO"-------Let"s Go-------\n");

 feeyu_dir=proc_mkdir("2",NULL);

 processinfo_("processinfo",0,cg_dir,processinfo_read_procmem, NULL );

 return 0; } void mod_exit_readprocess(void) {

 remove_proc_entry("processinfo",cg_dir);

 remove_proc_entry("2",NULL);

 printk(KERN_INFO"--------Thank You--------\n"); } int processinfo_read_procmem(char *page,char **start,off_t offset,int count,int *eof,void *data) {

 int len=0;

 struct task_struct *p;

 printk("所有内核进程信息:\n");

 for_each_process(p)

 {

  len+=sprintf(page+len,"NAME:%sPID:%dSTATE:%ld\n",p->comm,p->pid,p->state);

 }

 return len;

  } Makefile 文件源代码: ifneq ($(KERNELRELEASE),)

 obj-m:=processinfo、o else

 KDIR:= /lib/modules/$(shell uname -r)/build

 PWD:= $(shell pwd) default:

 $(MAKE) -C $(KDIR) M=$(PWD) modules clean:

 $(MAKE) -C $(KDIR) M=$(PWD) clean Endif 加载模块:

 查瞧模块就是否存在:

 查瞧模块信息:

 查瞧进程信息:

 卸载模块后

  实验总结 这次实验内容较多,重要就是通过一些命令与代码对内核模块的进程进行操作。使用命令对系统内核模块进行操作,通过 processinfo 文件与 makefile 文件对内核中的进程进行读写等操作。实验很繁杂。但思路清晰后也能较完整的把整个实验做下来。通过这次实验,我对内核模块的操作及内核的一些进程上的操作有的一定的了解。

 实验四 统计操作系统缺页次数 实验目的 学习虚拟内存的基本原理与 Linux 虚拟内存管理技术; 深入理解、掌握 Linux 的按需调页过程; 掌握内核模块的概念与操作方法,与向/proc 文件系统中增加文件的方法; 综合运用内存管理、系统调用、proc 文件系统、内核编译的知识。

 实验内容 1 1 、原理

 Linux的虚拟内存技术采用按需调页,当CPU请求一个不在内存中的页面时,会发生缺页,缺页被定义为一种异常(缺页异常),会触发缺页中断处理流程。每种 CPU 结构都提供一个do_page_fault 处理缺页中断。由于每发生一次缺页都要进入缺页中断服务函数do_page_fault 一次,所以可以认为执行该函数的次数就就是系统发生缺页的次数。因此可以定义一个全局变量 pfcount 作为计数变量,在执行 do_page_fault 时,该变量值加 1。本实验通过动态加载模块的方法,利用/proc 文件系统作为中介来获取该值。

 2 2 、实验环境

 操作系统:Ubuntu 12、04(内核版本为 3、2、0-23-generic-pae) 内核源码:linux-3、2、58

 实验过程 1. 下载一份内核源代码并解压

 Linux 受 GNU 通用公共许可证(GPL)保护,其内核源代码就是完全开放的。现在很多 Linux的网站都提供内核代码的下载。推荐使用 Linux 的官方网站:、kernel、org。

 在 terminal 下可以通过 wget 命令下载源代码: $ cd /tmp $ wget 、kernel、org/pub/linux/kernel/v3、x/linux-3、2、58、tar、xz 切换到 root 身份,解压源代码到/usr/src 目录下: # xz –d linux-3、2、58、tar、xz # tar –xvf linux-3、2、58、tar –C /usr/src 2 、 修改内核源代码, , 添加统计变量 1、切换到预编译内核目录 #cd /usr/src/linux-3、2、58 2、修改处理内存访问异常的代码 //用 vi 编辑器打开 fault、c,一般使用 Intel x86 体系结构,则修改 arch/x86/目录下的文件 #vi arch/x86/mm/fault、c #cd arch/x86/mm #sudo gedit fault、c

 //在 do_page_fault 函数的上一行定义统计缺页次数的全局变量 pfcount unsigned long volatile pfcount; //将 pfcount 加入到 do_page_fault 中,用以统计缺页次数

 pfcount++; 3、修改内存管理代码 //用 vi 编辑器打开头文件 mm、h

 #vi include/linux/mm、h //在 mm、h 中加入全局变量 pfcount 的声明,代码加在 extern int page_cluster;语句之后 extern unsigned long volatile pfcount; 4、导出 pfcount 全局变量,让整个内核(包括模块)都可以访问。方法就是: #cd kernel #sudo gedit kallsyms、c //在文件最后加入一行代码 EXPORT_SYMBOL(pfcount);

 3. 配置编译新内核 用编译 Linux 内核预备实验中的方法完成新内核的配置、编译、替换,重启后验证就是否完成替换。

 在编译内核前,一般来说都需要对内核进行相应的配置。配置就是精确控制新内核功能的机会。配置过程也控制哪些需编译到内核的二进制映像中(在启动时被载入),哪些就是需要时才装入的内核模块(module)。

 首先进入内核源代码目录: # cd

 /usr/src/linux-3、2、58 如果不就是第一次编译的话,有必要将内核源代码树置于一种完整与一致的状态。因此,推荐执行命令 make mrproper。它将清除目录下所有配置文件与先前生成核心时产生的、o 文件: #make mrproper

 (如果就是第一次可跳过此步) 然后配置编译选项(此处使用原内核的配置文件,完整的配置命令瞧操作提示): # cp /boot/config-3、2、0-20-generic-pae

 、config 该命令的作用就是将原内核配置文件拷贝的当前目录下,并命名为、config。若需要进一步修改配置请参照操作提示。

 在编译前用#uname -r 查瞧原来的版本

 4 、 编译内核与模块 编译内核,就用: #make 编译内核需要较长的时间,具体与机器的硬件条件及内核的配置等因素有关(采用 VMWare 虚拟机,需要约 60 分钟)。完成后产生的内核文件 bzImage 的位置在/usr/src/linux/arch/i386/boot目录下,当然这里假设用户的 CPU 就是 Intel x86 型的,并且您将内核源代码放在/usr/src/linux目录下。

 如果选择了可加载模块,编译完内核后,要对选择的模块进行编译,可用: #make modules 5. 安装新内核模块与新内核 首先,用下面的命令将新内核模块安装到系统的标准模块目录中: #make modules_install

  此处有改动选择了取消

 然后,用下面的命令将新内核安装到系统中:

 # make install

 通常,Linux 在系统引导后从/boot 目录下读取内核映像到内存中。因此如果想要使用自己编译的内核,就必须用 make install 命令将启动文件(内核映像)安装到/boot 目录下。

 6 、 编写读取 pfcount 值的模块代码 系统重启后,执行如下操作: #mkdir source

 //在当前用户目录下创建 source 文件夹,用于存放编写的用户程序 #cd source

  //切换到 source 目录 #vi pf、c

  //新建用于构建模块的代码 -------------------------------------------- /*pf、c*/

 /*modules program*/

 #include <linux/init、h> #include <linux/module、h> #include <linux/kernel、h> #include <linux/mm、h> #include <linux/proc_fs、h> #include <linux/string、h> #include <asm/uaccess、h> struct proc_dir_entry *proc_pf;

 struct proc_dir_entry *proc_pfcount; extern unsigned long pfcount; static inline struct proc_dir_entry *proc_pf_create(const char* name, mode_t mode, read_proc_t * get_info) {

  return create_proc_read_entry(name,mode,proc_pf,get_info,NULL); } int get_pfcount(char *buffer, char **start, off_t offset, int length, int *peof, void *data) {

  int len = 0;

  len = sprintf(buffer, "%ld \n", pfcount);

  return len; } static int pf_init(void) {

  proc_pf = proc_mkdir("pf", 0);

  proc_pf_create("pfcount", 0, get_pfcount);

  return 0; } static void pf_exit(void) {

  remove_proc_entry("pfcount",proc_pf);

  remove_proc_entry("pf",0); } module_init(pf_init); module_exit(pf_exit); MODULE_LICENSE("GPL"); 7 编译、构建内核模块 #vi Makefile

 //在 source 目录下建立 Makefile 文件 在 Makefile 中添加如下内容: obj-m := pf、o ifneq ($(KERNELRELEASE),)

 obj-m:=pf、o

 else

 KDIR:= /lib/modules/$(shell uname -r)/build

 PWD:= $(shell pwd) default:

 $(MAKE) -C $(KDIR) M=$(PWD) modules clean:

 $(MAKE) -C $(KDIR) M=$(PWD) clean endif 8 加载模块到内核中 执行加载模块命令: #insmod pf、ko 查瞧统计缺页次数: #cat /proc/pf/pfcount

 实验 总结

 实验中的更换 linux 内核的实验我开始没做出来,后来请教同学才明白过来,但内核更换确实需要多多的练习与学习。内核实验中也学到了一些关于内核的知识,重要的还就是自己要多多的练习,达到自己能独立完成内核更换的实验。

 实验五 EXT4 文件系统结构分析 一、实验目的: 掌握文件系统的工作机理;理解文件系统的主要数据结构;学习较为复杂的 Linux 下的编程;了解 EXT4 文件系统的结构。

 二、实验平台: 虚拟机:VMWare9 操作系统:Ubuntu12、04 文件系统:EXT4 编辑器:Gedit | Vi

 三、实验内容: (1)该实验要求编写程序,完成以下功能(注意保存截图): 1、查瞧主硬盘设备名、挂载目录及文件系统信息

 2、程序编译 进入 check_ext4fs 目录,输入 make clean; make 编译程序,生成 check_ext4fs 程序:

 获取 ext4 文件系统超级块,并显示超级块数据结构 ext4_super_block 的字段信息;

 获取块组描述符表,并能根据输入的块组号显示该块组描述符ext4_group_desc的字段信息;

  先获取组块描述表

 info groups [1, 33]

 获取索引节点表,并能根据输入的索引节点号(比如根目录文件的索引节点号就是 2),显示其索引节点数据结构 ext4_inode 的字段信息。

 (2)分析上述实验代码,回答下列问题: 大小(单位用字节):逻辑块、超级块 ext4_super_block、组描述符 ext4_group_desc、索引

 节点 ext4_inode; 逻辑块大小 4096 、超级块大小

 、组描述符 ext4_group_desc 大小 512 块、索引节点大小 256 字节 个数及位置:块组 0 中组描述符占用的块数 708 及所占块号 1057-1568、inode 个数及inode 表占用的块数 1057、块位图 block bitmap 占用块数 1025 及所在块号 1025、索引节点位图 inode bitmap 占用块数 1041 及所在块号 1041; 验证:执行 sudo dumpe2fs /dev/sda1 | more 命令,验证上述分析就是否正确。

  实验总结

 这次实验中,我了解了文件系统的基本工作原理,也明白了文件系统的主要数据结构,了解了 EXT4 文件系统的结构。实验过程中也出现过一些错误,在最后的数据验证部分,有一部分文件没有找到相对应的数据。经同学的指点,最终还就是完成了整个实验。

推荐访问:中原 工学院 操作系统

版权所有:格斯文档网 2010-2024 未经授权禁止复制或建立镜像[格斯文档网]所有资源完全免费共享

Powered by 格斯文档网 © All Rights Reserved.。浙ICP备19042928号