7
17
2014
0

将文件系统模块化

背景:

    想研究一下下文件系统,看看源码,源码中加上printk打印,辅助理解ls  cd mkdir等指令的函数调用过程。由于printk是需要时添加,这果断需要将文件系统模块化,在源码中新加入printk后,重新编译模块,再插入模块,再对该模块进行观察。所以现在需要先解决第一步:如何将文件系统模块化。

 

问题:

将ext2,ext3,ext4文件系统模块化

解决问题:

   step1.重新编译内核

   目的是在make menuconfig这一步中将ext2,ext3,ext4这三个部分变成模块化而不是嵌入内核的结构: 即由 * 改成M.

      ps :step1 小tips 

      tip1:在编译内核前,你需要先看看你当前的内核的ext2,ext3,ext4是否已经是模块化的状态。方法如下

cd /usr/src/linux-2.6.34.14/

gedit .config
查看config文件,在弹出的框中搜索ext2,我们可以看到CONFIG_EXT2_FS=m。这说明当前的配置ext2是以模块的形式存在的。若CONFIG_EXT2_FS=y,则ext2的代码是嵌入内核的。 
 
 
       
 
tip2:在make menuconfig步骤中,会弹出一个对话框,这是可以可以通过顶行提示语"</>for search" ,使用/ext2 来找到修改配置文件的位置:输入/ext2 ,由下图可以看到ext2的修改位置在 File system目录下
 
 
上图输入 /ext2
 
 
 
上图可以看到含有ext2参数的路径位置
 
 
       tip3:找到对应位置后,通过空格键,将其变成M的模式
 
 
 
step2:修改文件系统中Makefile文件。
运行重新编译的内核。将内核源码目录下\linux-2.6.34.14\fs\ext2文件拷贝到/home/modulefs文件夹,修改/home/modulefs/ext2中的Makefile文件:
源文件如下:
#
# Makefile for the linux ext2-filesystem routines.
#
#

obj-$(CONFIG_EXT2_FS) += ext2.o

ext2-y := balloc.o dir.o file.o ialloc.o inode.o \
	  ioctl.o namei.o super.o symlink.o

ext2-$(CONFIG_EXT2_FS_XATTR)	 += xattr.o xattr_user.o xattr_trusted.o
ext2-$(CONFIG_EXT2_FS_POSIX_ACL) += acl.o
ext2-$(CONFIG_EXT2_FS_SECURITY)	 += xattr_security.o
ext2-$(CONFIG_EXT2_FS_XIP)	 += xip.o

修改后Makefile文件如下:

#
# Makefile for the linux ext2-filesystem routines.
#

obj-m += ext2.o

ext2-objs := balloc.o dir.o file.o ialloc.o inode.o \
	  ioctl.o namei.o super.o symlink.o
KERNELDIR:=/usr/src/linux-2.6.34.14/ 
PWD:=$(shell pwd)
ext2-$(CONFIG_EXT2_FS_XATTR)	 += xattr.o xattr_user.o xattr_trusted.o
ext2-$(CONFIG_EXT2_FS_POSIX_ACL) += acl.o
ext2-$(CONFIG_EXT2_FS_SECURITY)	 += xattr_security.o
ext2-$(CONFIG_EXT2_FS_XIP)	 += xip.o

default:
	make -C $(KERNELDIR) M=$(PWD) modules
clean:
	rm -rf *.o *.mod.c *.ko *.symvers

各行的意思可以参照我上一篇博客,这里的主要目的是将编译进入内核的文件系统(与*对应)的Makefile,转化为模块化(与M对应)类型的生成模块的Makefile。

 

step3:编译模块,插入模块

在/home/modulefs/ext2目录下的代码中加入你想插入的printk语句。输入如下指令

cd /home/modulefs/ext2
make clean
make
insmod ext2.ko
mkfs.ext2 /dev/ram0
mkdir /mnt/ram0
mount /dev/ram0 /mnt/ram0

这样就将/mnt/ram0上挂载的就是你插入printk语句的文件系统了。

通过dmesg -c指令可以看到printk对应的输出。

  

问题解决的过程:

上述三个步骤看上去简单,可是在这个过程中会碰到各种蛋疼得到死的问题。

问题一:ismod:error inserting 'ext2.ko':-1 Device or resource busy

老出现如下错误:

 

 

这个原因有两种:

原因一:内核的config配置CONFIG_EXT2_FS=y。y表示编译进了内核,所以insmod ext2.ko时,会与内核中已经有的ext2相冲突。

解决:这个问题在于你的make menuconfig这个步骤配置文件没有由* 改为 m,可以在/usr/src/linux-2.6.34.14/目录下输入gedit .config,然后查找CONFIG_EXT2_FS的状态。在这种情况下你需要重新编译内核,娃啊~~好惨~~~

 

原因二:ext2文件系统已经在使用,系统在使用内核linux-2.6.34.14\fs\ext2目录下的文件系统,而不是/home/modulefs/ext2目录下的文件系统。具体说明如下:

按照step1的要求编译好内核后,此时lsmod,是没有ext2这个模块的。然后直接输入如下指令

mkfs.ext2 /dev/ram0

这是lsmod还是没有ext2。此时输入

mount /dev/ram0 /mnt/ram0

这是lsmod,你会发现出现了ext2模块,也就是说系统直接帮挂载了ext2模块。而系统默认挂载的模块是linux-2.6.34.14\fs\ext2目录下的。也就是说并非为你想观察的加入了printk语句的ext2模块。这是你如果再插入你加入printk语句的ext2模块,显然就会发生冲出

解决方法

你需要在系统未给你插入模块之前,手动插入你加入的模块。在/home/modulefs/ext2目录下输入

cd /home/modulefs/ext2
make clean
make
insmod ext2.ko
mkfs.ext2 /dev/ram0
mount /dev/ram0 /mnt/ram0

 所以说从问题2,我们可以总结出系统盘所在的文件系统类型肯定是通过上述方法模块化的,由你加入printk语句后在插入观察的。(具体的方法见博客 “模块化系统盘所在的文件系统”)原因如下:

比如说我的系统盘为sda1,文件系统类型为ext4,那么虽然我把ext4变成了M类型,但是由于开机自动运行了系统,所以linux-2.6.34.14\fs\ext4目录下生成的模块被自动挂载。所以说只要一开机lsmod中就会有ext4模块。那么我也就不能愉快的按照自己的意愿在/home/modulefs/ext4目录下插入printk,然后插入ext4模块了。

 

最后附加点小心得:

我在同一个系统中把linux-2.6.34.14编译了两次,一次ext文件系统时嵌入内核的,另一次为模块化的。编译好后,开机是,系统能自动将两次不同的编译用old来标志。如何区分呢?

第一:名字*old肯定是老的版本咯

第二:ls -l * 通过显示的时间判断

 

 

可以看到config-2.6.34.14与config-2.6.34.14.old的不同的创建时间。

 

 

Category: 文件系统 | Tags: 模块化;文件系统 | Read Count: 1211

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com