导言:
本文是操作系统课设题目,主要参考大佬的文章:
https://blog.csdn.net/qq_17447307/article/details/103649354
在实现过程中遇到了很多的问题,因此记录下来,用作复习笔记,也希望可以给大家提供一些帮助,少走些弯路。
题目2:实现基于模块的文件系统
修改ext3或ext4的源代码,实现新的文件系统。
要求:
(1)复制ext3或ext4的源代码,修改Makefile文件,使用模块编译方式,需要重新编译Linux内核。
(2)可以动态加载和卸载新的文件系统。
(3)至少需要修改文件系统的名称,最好能对文件写操作向系统后台打印出信息
设计思路
使用虚拟机完成,通过镜像文件安装虚拟机linux(使用centos7版本)
下载内核源码 使用的是4.14.260
1、安装虚拟机
2、内核解压问题(在这里出现了很多错误)
-
首先确定内核的版本 ,以centos7为例的话,内核版本不能高于5.0,否则会出现gcc版本不支持的问题。(centos7的gcc版本为4.8)所以推荐下载内核低于5.0的 比如我下载的4.14.260
-
其次是虚拟机和本地电脑的文件共享问题
(1)直接拖放,直接把本地文件拖到虚拟机的桌面,或者用户文件夹。(不能拖到root模式的文件夹)
如果出现不能拖放的问题,可以重新安装下虚拟机tools,如下图,点击重新安装之后不用动,过一会。(或者手动解压,比较麻烦)
(2)共享文件夹实现传输 虚拟机设置里开启共享文件夹 本地电脑里新建一个文件夹用来存放信息,如下图
(3)解压源码文件 首先在你压缩文件所在的文件夹右键打开终端 (也可以用cd命令进入所在文件夹)然后使用如下解压命令,即可解压到/usr/src下:
tar -xvJf linux-4.14.260.tar.xz -C/usr/src
一、内核安装
su 输入正确的root密码获取超级权限,以下指令都是在获取超级权限的情况下执行的。
安装内核编译工具
yum -y install gcc gcc-c++ ncurses ncurses-devel cmake elfutils-libelf-devel openssl-devel
编辑内核配置文件
-
进入文件夹: cd /usr/src/
-
解压缩源码到指定路径 tar -xvJf linux-4.14.260.tar.xz -C/usr/src
-
进入源码文件夹: cd linux-4.14.260
-
编辑内核配置文件: make menuconfig
选择“General setup”->”Local version”,输入自定义的本地内核版本号用以区分,以“-js”为例。
然后返回主页面,选择“File systems”,确保选项 The Extended 4(ext4)filesystem前面是M,即ext4文件系统为模 块 化加载,若不是 选中按“M”键。最后选择“save”保存**.config**配置文件即可。
-
开始编译 编译文件(使用4个核心)
make -j4 时间较久 (4个核心用时半个小时左右)
如下图表示成功
****
安装模块: make modules_install
重启并选择新内核
如图应选择修改过的内核版本 即为第一个 -js 后面为自己定义的本地内核版本号
二、新文件系统模块化
拷贝内核源码文件夹下 fs/ext4
文件夹里的所有内容,放到其他位置。
进入文件夹:
cd /usr/src/linux-4.14.260/fs
复制到/usr/src:
cp -r ext4 /usr/src/ext4edit
打开ext4edit文件系统根目录下的Makefile文件,修改为:
obj-$(CONFIG_EXT4_FS) += ext4edit.o
ext4edit-y := balloc.o bitmap.o block_validity.o dir.o ext4_jbd2.o extents.o \
extents_status.o file.o fsmap.o fsync.o hash.o ialloc.o \
indirect.o inline.o inode.o ioctl.o mballoc.o migrate.o \
mmp.o move_extent.o namei.o page-io.o readpage.o resize.o \
super.o symlink.o sysfs.o xattr.o xattr_trusted.o xattr_user.o
KERNELDIR:=/usr/src/linux-4.14.160
PWD:=$(shell pwd)
ext4edit-$(CONFIG_EXT4_FS_POSIX_ACL) += acl.o
ext4edit-$(CONFIG_EXT4_FS_SECURITY) += xattr_security.o
default:
make -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o *.mod.c *.ko *.symvers
其中KERNELDIR变量为内核源代码位置,PWD变量为当前工作目录的绝对路径,也就是Ext4edit文件系统源码所在路径。在Makefile文件的最后再加上两行编译命令,用以编译模块和清除编译产生的文件。
接着,找到文件夹里super.c,这是文件系统挂载是所要用到的文件。找到其中的结构体类型为file_system_type的变量 ext4_fs_type,修改其中的name字段和函数MODULE_ALIAS_FS()的参数为“ext4edit”。后者作用是设置模块别名。具体代码如下。
static struct file_system_type ext4_fs_type = {
.owner = THIS_MODULE,
.name = "ext4edit",
.mount = ext4_mount,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
MODULE_ALIAS_FS("ext4edit");
然后找到sysfs.c
文件,这是与顶层虚拟文件系统相关的文件。找到初始化函数ext4_init_sysfs()
,修改里面第二行kobject_set_name()
里的字段为“ext4edit”
。具体代码如下。
int __init ext4_init_sysfs(void)
{
int ret;
kobject_set_name(&ext4_kset.kobj, "ext4edit");
ext4_kset.kobj.parent = fs_kobj;
ret = kset_register(&ext4_kset);
if (ret)
return ret;
ret = kobject_init_and_add(&ext4_feat, &ext4_feat_ktype,
NULL, "features");
if (ret)
kset_unregister(&ext4_kset);
else
ext4_proc_root = proc_mkdir(proc_dirname, NULL);
return ret;
}
至此,基于Ext4的新文件系统Ext4edit改写完成。
我们可以修改该文件系统的代码,实现自定义的功能。例如,在该文件系统中添加写缓存提示功能。这个功能需要用到file.c文件。找到该文件后在该文件里ext4_file_write_iter()函数,添加一条printk()语句,打印提示信息。该函数用于写文件时延迟分配磁盘空间时,将数据按字节写入页缓存。添加的语句如下。
printk(“Method ext4_file_write_iter() in file.c.”);
三、模块编译及动态静态加载
1) 编译模块
重新打开命令行,并输入su命令和root密码获取超级权限。将文件系统的源码拷贝到/usr/src/目录下。
进入模块文件夹:
cd /usr/src/ext4edit
编译模块:
make
2).加载文件系统
insmod ext4edit.ko
如出现“Unknown symbol“错误,使用modinfo ext4edit.ko命令,查看模块信息,信息中有depends一项表示依赖的模块,使用modprobe先加载依赖的模块即可。Ext4edit文件系统依赖于mbcache和jbd2两个模块。
3).挂载文件系统
进入/dev目录:
cd /dev
创建块设备文件:
mknod -m 640 js b 1 0
格式化块设备文件
mkfs.ext4 js
进入/mnt目录:
cd /mnt
创建js文件夹:
mkdir js
挂载文件系统:
mount /dev/js -t ext4edit /mnt/js
查看挂载信息:
df -T -h
执行结果的最后一条显示文件系统类型为ext4edit的文件系统已挂载在/mnt/js目录下,说明挂载完成。
进入 /mnt/js 目录下,使用“ vim hello.txt ”创建并打开名为
hello.txt 的文本文件,使用 i 切换为INSERT模式写入“
hello,Linux!”,并按
ESC,键入“
:wq”保存并退出。输入“
dmesg -c `”查看后台信息,查看结果如下图所示。
查看安装的模块:
lsmod | 查看已安装到内核的模 |
---|
2).卸载文件系统
卸载文件系统:
umount /mnt/yoching
移除模块:
rmmod ext4edit