Teach yourself “自主知识产权” in 2 hours

咱们中国人似乎一直很热衷并且很擅长于创造“自主知识产权”的东西,一直很纳闷,直到今天翻开这次的操作系统实验指导一看,才知道原来这玩意这么容易!我们不妨来亲自实践一下,内容就是这次的操作系统实验:为 Linux 内核添加一个新的文件系统(听上去是很浩大的工程啊!):

第一步:准备工作【30 min】

所谓“工欲善其事,必先利其器”,这次我们的工作环境是 Linux ,为了方便起见,我使用我熟悉的 Debian GNU/Linux 系统。
  1. 从校内的 FTP 下载 Debian Etch 安装光盘。【10 min】
  2. 安装基本子系统,连接网络源,安装必要工具(如 emacs 、sudo 等),升级并安装内核开发包(如 kernel-package 、fakeroot 等)。【15 min】
  3. 下载并解压最新内核源代码。【5 min】

第二步:准备模板【0.5 min】

我们的新的自主知识产权的文件系统将“从 ext2 文件系统中汲取灵感”,虽然现在的内核中已经连 ext4 都有了,不过为了保证 KISS 原则,我们还是选了更简单的 ext2 :

$ cd fs
$ cp -a ext2 myext2            # our new filesystem is called myext2
$ cd ../include/linux
$ for f in ext2* ; cp $f my$f  # zsh rocks!

第三步:初步打磨:【1.5 min】

  1. 打开 Emacs ,用 dired 打开 fs/myext2 。
  2. 用 % m 并输入 .* 标记所有文件。
  3. 按 Q 进行替换,输入要替换的词 ext2 以及替换后的词 myext2 。
  4. Emacs 会在每个文件中替换之前询问你,按下 ! 即可全部替换!Emacs 自动判断大小写,ext2 会被替换为 myext2 ,而 EXT2 会被替换为 MYEXT2 。Wow!Emacs rocks!简直就是专门为创造“自主知识产权而打造的编辑器!
  5. 再打开 include/linux 。
  6. 用 % m 标记文件名匹配 ^myext2.* 的文件。
  7. 替换。

第四步:精雕细琢【5 min】

  1. 在 fs/Makefile 和 fs/KConfig 中邻近 ext2 的地方都复制一份同样的代码,并把 ext2 改为 myext2 。【1 min】
  2. 在 fs/myext2 中把 ext2.h 重命名为 myext2.h 。【0.5 min】
  3. 将 include/asm-generic/bitops 目录下的 ext2* 里面的内容全部复制一份,就放在原来的文件中,把复制的代码中的 ext2 替换为 myext2 。只需选中复制出来的文本,然后按下 M-% ,Emacs 会自动记住上次的替换选项,正好是我们想要的,直接回车,然后按下 ! 即可替换选中的部分的所有 ext2 。【1.5 min】
  4. 将 include/asm-x86/bitops_32.h 中的 ext2_set_bit_atomic 和 ext2_clear_bit_atomic 如前一步骤那样炮制一份 myext2 的。【1.5 min】
  5. 在 include/linux/magic.h 中添加 #define MYEXT2_SUPER_MAGIC 0x6666 ,六六大顺啊!【0.5 min】

第五步:周边建设【15 min】

既然修改了 Magic Number ,就不能继续用 mkfs.ext2 了,所以要自己做一个,这个也好做,先让 mkfs.ext2 来创建文件系统,然后我们搜索 super block ,并把其中的 Magic Number 改掉:

#!/usr/bin/ruby

# see structure of +ext2_super_block+ ENCODING = "IIIIIIIIIIIIISSSSSSIIIISS".freeze

I_MAGIC = 15 I_LOG_BLOCK_SIZE = 6 I_BLOCKS_PER_GROUP = 8 I_BLOCKS_COUNT = 1

INITIAL_SB_POS = 1024 SB_SIZE = 84

EXT2_MAGIC = 0xef53 MYEXT2_MAGIC = 0x6666

def fix_magic(device) fixcount = 1 File.open(device, "rb+") do |f| f.sysseek(INITIAL_SB_POS) info = f.sysread(SB_SIZE).unpack(ENCODING) if info[I_MAGIC] != EXT2_MAGIC p "Damaged ext2 filesystem, can't convert into myext2." exit 2 end

info[I_MAGIC] = MYEXT2_MAGIC f.sysseek(INITIAL_SB_POS) f.syswrite(info.pack(ENCODING))

group_size = 1024*(1 << info[I_LOG_BLOCK_SIZE])*(info[I_BLOCKS_PER_GROUP]) pos = group_size tail = 1024*(1 << info[I_LOG_BLOCK_SIZE])*info[I_BLOCKS_COUNT]

loop do break if pos >= tail f.sysseek(pos+INITIAL_SB_POS) info = f.sysread(SB_SIZE).unpack(ENCODING) if info[I_MAGIC] == EXT2_MAGIC info[I_MAGIC] = MYEXT2_MAGIC f.sysseek(INITIAL_SB_POS) f.syswrite(info.pack(ENCODING)) fixcount += 1 end pos += group_size end end

fixcount end

# main if ARGV.length < 1 p "Usage: #{__FILE__} device file" exit 1 end

system("/sbin/mkfs.ext2 #{ARGV[0]}") puts "#{fix_magic(ARGV[0])} super block converted"

第六步:标新立异【2 min】

既然是“自主知识产权”的东西,当然不能和现有的东西完全一样,得有自己的特点。可以修改一些文件操作,可是修改成什么样呢?什么样都太麻烦,干脆去掉一些文件操作好了,比如,把软链接支持去掉,就可以和原有的 ext2 区分开了!修改 fs/myext2/namei.c 中的 myext2_symlink 函数:

static int myext2_symlink (struct inode * dir, struct dentry * dentry,
        const char * symname)
{
    printk("<1>symlink not supported by myext2!\n");
    return -EPERM;
}

第七步:大功告成【66 min】

编译内核:

$ fakeroot make-kpkg --initrd --append-to-version=newfs --revision=1.0 kernel_image

编译好以后就是一些 deb 包,就是添加了我们的新的文件系统的内核了。再配合上 mkfs.myext2 发布出去,就是一个产品!

虽然大部分时间都是在下载、安装和编译,但是要做一个“自主知识产权”的产品其实也还是蛮累的,哈!好了,玩笑到此结束。我的实验报告也算是做完了。对于这样的操作系统实验呢,我也不知道该怎么说才好。如果说一切还得靠自己直觉的话,就没有什么话好说了,如果说课堂上教授的东西以及课后作业还是应该对学生有更好的效果的话,这个却是不那么好。

整个实验做下来,我想初衷根本没有达到,我现在还是对 Linux 的文件系统的运作了解非常模糊(而且这一点点模糊的了解还是从其他地方得来的),而且老是给的指导资料完全是 2.4 内核的,用 2.6 内核来做好歹还有一些摸索的过程,也算有点收获,如果大家都去下一个 2.4 的内核,按照实验指导书上依次做下来,估计也就是把时间花在编译内核上了,到最后也是什么都没明白。 :(

Comments (4)

shixiaoyu January 02, 2008
555555555太难了,看不懂,这边看你的blog,这边看老师的教程,天啊,我崩溃了。。。
is July 13, 2008
...,真无语啊,还有这样的作业...
pluskid July 13, 2008
@is,
我想国内的大学普遍是这样吧? -.-bb
pluskid December 18, 2009
唔,我怎么觉得这个脚本有个 bug 呢?写回的时候每次 fseek 都是到 INITIAL_SB_POS 应该是不对的吧? -.-bb