操作系统实验指导书 联系客服

发布时间 : 星期三 文章操作系统实验指导书更新完毕开始阅读d221c4e690c69ec3d4bb757a

fs/ext2/balloc.c fs/ext2/bitmap.c fs/ext2/dir.c fs/ext2/ext2.h fs/ext2/file.c fs/ext2/fsync.c fs/ext2/ialloc.c fs/ext2/inode.c fs/ext2/ioctl.c fs/ext2/namei.c fs/ext2/super.c fs/ext2/symlink.c fs/ext2/xattr.c fs/ext2/xattr.h

fs/ext2/xattr_security.c fs/ext2/xattr_trusted.c fs/ext2/xattr_user.c fs/ext2/xip.c fs/ext2/xip.h

include/linux/ext2_fs.h include/linux/ext2_fs_sb.h

有了这些初步的信息后(当然这些信息是否正确,还需后面的检验),我们接下来开始添加myext2文件系统的源代码到Linux源代码。

由于本节工作是要克隆ext2文件系统到myext2文件系统,所以我们需要把ext2部分的源代码克隆到myext2去,即复制一份以上所列的ext2源代码文件给myext2用。按照Linux源代码的组织结构,我们把myext2文件系统的源代码存放到fs/myext2下,头文件放到include/linux下。在Linux的shell下,执行如下操作(也许需要先转成root用户):

#cd /usr/src/linux #cd fs

#cp –R ext2 myext2 #cd ../include/linux

#cp ext2_fs.h myext2_fs.h

#cp ext2_fs_sb.h myext2_fs_sb.h #cd /usr/src/linux/fs/myext2 #mv ext2.h myext2.h

这样就完成了克隆文件系统工作的第一步——源代码复制。对于克隆文件系统来说,这样当然还远远不够,因为文件里面的数据结构名、函数名、以及相关的一些宏等内容还没有根据myext2改掉,连编译都通不过。

下面我们开始克隆文件系统的第二步:修改上面添加的文件的内容。为了简单起见,我们做了一个最简单的替换:将原来*EXT2*替换成*MYEXT2*;将原来的*ext2*替换成*myext2*。

如果读者是使用vi编辑单个文件的话,可以使用类似于这样的替换命令:

:%s/EXT2/MYEXT2/gc :%s/ext2/myext2/gc

对于fs/myext2下面文件中字符串的替换,也可以使用下面的脚本:

#!/bin/sh

SCRIPT=substitute.sh

for f in *; do

if [ $f = $SCRIPT ]; then echo \ continue fi

echo -n \ cat $f | sed 's/ext2/myext2/g' > ${f}_tmp mv ${f}_tmp $f echo \

echo -n \ cat $f | sed 's/EXT2/MYEXT2/g' > ${f}_tmp mv ${f}_tmp $f echo \

done

33

把这个脚本命名为substitute.sh,放在fs/myext2下面,加上可执行权限,运行之后就可以把当前目录里所有文件里面的“ext2”和“EXT2”都替换成对应的“myext2”和“MYEXT2”。

完成这一步之后,我们可以用diff来看看修改后的代码。

# diff -Naur fs/ext2/ fs/myext2/ > /home/kai/myext2.diff

改动的地方还比较多,例如:

--- include/linux/ext2_fs.h 2006-01-02 22:21:10.000000000 -0500 +++ include/linux/myext2_fs.h 2007-08-15 05:35:06.000000000 -0400 @@ -1,5 +1,5 @@ /*

- * linux/include/linux/ext2_fs.h + * linux/include/linux/myext2_fs.h …

-struct ext2_inode { +struct myext2_inode { __le16 i_mode; /* File mode */ __le16 i_uid; /* Low 16 bits of Owner Uid */ __le32 i_size; /* Size in bytes */ @@ -231,7 +231,7 @@ __le32 m_i_reserved1; } masix1; } osd1; /* OS dependent 1 */

- __le32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */ + __le32 i_block[MYEXT2_N_BLOCKS];/* Pointers to blocks */ __le32 i_generation; /* File version (for NFS) */ __le32 i_file_acl; /* File ACL */ __le32 i_dir_acl; /* Directory ACL */ @@ -294,51 +294,51 @@ /*

* File system states */

-#define EXT2_VALID_FS 0x0001 /* Unmounted cleanly */ -#define EXT2_ERROR_FS 0x0002 /* Errors detected */ +#define MYEXT2_VALID_FS 0x0001 /* Unmounted cleanly */ +#define MYEXT2_ERROR_FS 0x0002 /* Errors detected */ …

再如:

--- fs/ext2/namei.c 2007-08-13 21:47:12.000000000 -0400 +++ fs/myext2/namei.c 2007-08-15 06:13:32.000000000 -0400 …

-static inline void ext2_inc_count(struct inode *inode) +static inline void myext2_inc_count(struct inode *inode) { inode->i_nlink++; mark_inode_dirty(inode); }

-static inline void ext2_dec_count(struct inode *inode) +static inline void myext2_dec_count(struct inode *inode) { inode->i_nlink--; mark_inode_dirty(inode); }

-static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode) +static inline int myext2_add_nondir(struct dentry *dentry, struct inode *inode) {

- int err = ext2_add_link(dentry, inode); + int err = myext2_add_link(dentry, inode); if (!err) { d_instantiate(dentry, inode); return 0; }

- ext2_dec_count(inode); + myext2_dec_count(inode); iput(inode); return err; }

@@ -68,15 +68,15 @@

* Methods themselves. */

-static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)

+static struct dentry *myext2_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) {

34

struct inode * inode; ino_t ino;

- if (dentry->d_name.len > EXT2_NAME_LEN) + if (dentry->d_name.len > MYEXT2_NAME_LEN) return ERR_PTR(-ENAMETOOLONG);

- ino = ext2_inode_by_name(dir, dentry); + ino = myext2_inode_by_name(dir, dentry); inode = NULL; if (ino) { inode = iget(dir->i_sb, ino); @@ -86,7 +86,7 @@ return d_splice_alias(inode, dentry); } …

其它代码的修改类似。

好了,源代码的修改工作到此结束。接下来就是第三步工作——编译源代码。首先我们要把我们的myext2加到编译选项中去,以便在做make menuconfig的时候,可以将该选项加上去。由于2.6的内核编译系统相对于2.4做了很大的改进,添加一个模块或者文件的工作很简单。做这项工作只需要修改三个文件:

fs/Kconfig fs/Makefile

arch/i386/defconfig

fs/Kconfig中拷贝一份对应的对EXT2文件宏的定义和帮助信息,这样在做make menuconfig的时候可以查看该选项的有关帮助的内容。fs/Makefile的修改是告内核编译系统,当myext2对应的宏被选择上的时候,到fs/myext2目录下去编译myext2文件系统。defconfig是改动默认的编译选项,比如:

--- fs/Kconfig.bak 2007-08-15 07:14:11.000000000 -0400 +++ fs/Kconfig 2007-08-15 07:21:29.000000000 -0400 @@ -62,6 +62,62 @@ If you do not use a block device that is capable of using this, or if unsure, say N.

+config MYEXT2_FS

+ tristate \+ help

+ This is a test of adding a self-defined filesystem. +

+ To compile this file system support as a module, choose M here: the + module will be called myext2. +

+ If unsure, say Y. …

--- fs/Makefile.bak 2007-08-15 08:37:03.000000000 -0400 +++ fs/Makefile 2007-08-15 08:37:21.000000000 -0400 @@ -54,6 +54,7 @@

obj-$(CONFIG_EXT3_FS) += ext3/ # Before ext2 so root fs can be ext3 obj-$(CONFIG_JBD) += jbd/ obj-$(CONFIG_EXT2_FS) += ext2/ +obj-$(CONFIG_MYEXT2_FS) += myext2/ obj-$(CONFIG_CRAMFS) += cramfs/ obj-$(CONFIG_SQUASHFS) += squashfs/ obj-$(CONFIG_RAMFS) += ramfs/ …

--- arch/i386/defconfig.bak 2007-08-15 07:16:34.000000000 -0400 +++ arch/i386/defconfig 2007-08-15 07:17:07.000000000 -0400 @@ -1073,6 +1073,8 @@ #

CONFIG_EXT2_FS=y

# CONFIG_EXT2_FS_XATTR is not set +CONFIG_MYEXT2_FS=y

+# CONFIG_MYEXT2_FS_XATTR is not set CONFIG_EXT3_FS=y

CONFIG_EXT3_FS_XATTR=y

# CONFIG_EXT3_FS_POSIX_ACL is not set

详细的diff文件内容请从网站(os.zju.edu.cn)下载。

一切都准备就绪了,使用make menuconfig选择上myext2,如下:

# cd /usr/src/linux # make menuconfig

35

选中MY EXT2对应的选项:

保存修改,然后使用“make”命令编译连接生成新内核文件: 编译一切OK,只是在连接的时候出现了以下错误:

...

LD fs/built-in.o GEN .version

CHK include/linux/compile.h UPD include/linux/compile.h CC init/version.o LD init/built-in.o LD .tmp_vmlinux1

fs/built-in.o: In function `grab_block':fs/myext2/balloc.c:271: undefined reference to `myext2_test_bit'

:fs/myext2/balloc.c:285: undefined reference to `myext2_find_next_zero_bit' :fs/myext2/balloc.c:302: undefined reference to `myext2_test_bit'

:fs/myext2/balloc.c:307: undefined reference to `myext2_find_next_zero_bit' :fs/myext2/balloc.c:314: undefined reference to `myext2_set_bit_atomic' fs/built-in.o: In function `myext2_free_blocks':fs/myext2/balloc.c:239: undefined reference to `myext2_clear_bit_atomic' fs/built-in.o: In function `myext2_new_block':fs/myext2/balloc.c:490: undefined reference to `myext2_set_bit_atomic'

fs/built-in.o: In function `myext2_free_inode':fs/myext2/ialloc.c:151: undefined reference to `myext2_clear_bit_atomic' fs/built-in.o: In function `myext2_new_inode':fs/myext2/ialloc.c:495: undefined reference to `myext2_find_next_zero_bit'

:fs/myext2/ialloc.c:510: undefined reference to `myext2_set_bit_atomic' make: *** [.tmp_vmlinux1] Error 1 [root@localhost linux]#

只要编译不出现问题,连接错误还是比较好办的。从显示出来的错误分析,估计是缺了这些函数的定义。根据逆向思维方法,只要在Linux源代码中搜索ext2_test_bit,ext2_find_next_zero_bit等函数,找到它们之后,同样复制一份,改成myext2_test_bit,myext2_find_next_zero_bit等函数名就可以了。我们对这些函数逐个击破,先来搜索ext2_test_bit。在include/asm-i386/bitops.h中可以发现这些函数群。OK,无需客气,三下五除二,全部把它们复制一份再修改掉,我们已经看到胜利的曙光就在眼前了!

--- include/asm-i386/bitops.h.bak 2007-08-15 08:58:19.000000000 -0400 +++ include/asm-i386/bitops.h 2007-08-15 08:58:04.000000000 -0400 @@ -449,6 +449,19 @@ find_first_zero_bit((unsigned long*)addr, size) #define ext2_find_next_zero_bit(addr, size, off) \\ find_next_zero_bit((unsigned long*)addr, size, off) +#define myext2_set_bit(nr,addr) \\

+ __test_and_set_bit((nr),(unsigned long*)addr) +#define myext2_set_bit_atomic(lock,nr,addr) \\

+ test_and_set_bit((nr),(unsigned long*)addr) +#define myext2_clear_bit(nr, addr) \\

+ __test_and_clear_bit((nr),(unsigned long*)addr) +#define myext2_clear_bit_atomic(lock,nr, addr) \\

+ test_and_clear_bit((nr),(unsigned long*)addr)

+#define myext2_test_bit(nr, addr) test_bit((nr),(unsigned long*)addr) +#define myext2_find_first_zero_bit(addr, size) \\ + find_first_zero_bit((unsigned long*)addr, size) +#define myext2_find_next_zero_bit(addr, size, off) \\ + find_next_zero_bit((unsigned long*)addr, size, off)

36