||
yaffs2的补丁文件patch-ker分析
为内核打上yaffs2 补丁
(1)将yaffs2代码加入内核
这可以通过yaffs2目录下的脚本文件patch-ker.sh来给内核打补丁,用法如下:
usage: ./patch-ker.sh c/l kernelpath
if c/l is c, then copy. if l then link.
这表明,如果c/l是c,则yaffs2的代码会被复制到内核目录下,如果是l,则在内核的目录下创建一些链接文件。这里yaff2所在的目录/root/linux-test/,和linux-2.6.32.2在同一个目录下,执行如下命令打补丁:
[root@localhost yaffs2]# ./patch-ker.sh c /root/linux-test/linux-2.6.32.2
usage: ./patch-ker.sh c/l m/s kernelpath
if c/l is c, then copy. If l then link
if m/s is m, then use multi version code. If s then use single version code
[root@localhost yaffs2]# ./patch-ker.sh c s /root/linux-test/linux-2.6.32.2
*** Warning ***
You have chosen to use the single kernel variant of the yaffs VFS glue code
that only works with the latest Linux kernel tree. If you are using an older
version of Linux then you probably wanted to use the multi-version variant by
re-running the patch-ker.sh script using m as a the second argument.
ie ./patch-ker.sh c m /root/linux-test/linux-2.6.32.2
Updating /root/linux-test/linux-2.6.32.2/fs/Kconfig
Updating /root/linux-test/linux-2.6.32.2/fs/Makefile
[root@localhost yaffs2]#
注意第二个参数m/s,如果不指定,有时会执行失败。
上述命令完成下面三件事:
<1>修改内核文件/fs/Kconfig,增加下面两行(在177行附近):
if MISC_FILESYSTEMS
source "fs/adfs/Kconfig"
source "fs/affs/Kconfig"
source "fs/ecryptfs/Kconfig"
source "fs/hfs/Kconfig"
source "fs/hfsplus/Kconfig"
source "fs/befs/Kconfig"
source "fs/bfs/Kconfig"
source "fs/efs/Kconfig"
source "fs/yaffs2/Kconfig"
source "fs/jffs2/Kconfig"
# UBIFS File system configuration
<2>修改内核文件/fs/Makefile,增加下面两行(在129行附近):
obj-$(CONFIG_GFS2_FS) += gfs2/
obj-$(CONFIG_EXOFS_FS) += exofs/
obj-$(CONFIG_YAFFS_FS) += yaffs2/
<3>在内核文件的fs目录下创建yaffs2子目录,然后复制如下文件:
将yaffs2源码目录下的Makefile.kernel文件复制为内核fs/yaffs2/Makefile文件。
将yaffs2源码目录下的Kconfig文件复制为内核fs/yaffs2/目录下。
将yaffs2源码目录下的*.c、*.h文件(不包括子目录下的文件)复制为内核fs/yaffs2/目录下。
(2)配置内核选项
阅读内核fs/Kconfig文件可以了解各配置选项的作用。
以下是用到的几个选项:
<1>CONFIG_YAFFS_FS:支持yaffs文件系统。
<2>CONFIG_YAFFS_YAFFS2:支持yaffs2文件系统,对于每页大小为2k字节nand flash,需要选中这个选项。
<3>CONFIG_YAFFS_AUTO_YAFFS2:自动选择yaffs2文件格式,如果不配置这个选项,必须使用yaffs2字样来表示yaffs2文件系统格式,如果配置这个选项,则可以使用yaffs字样来统一表示yaffs1和yaffs2文件系统格式,驱动程序会根据nand flash的页大小自动分辨是yaffs1还是yaffs2。
patch-ker源代码分析:
#!/bin/sh
# args: l/c : link or copy
# kpath : Full path to kernel sources to be patched
#
# Somewhat "inspired by" the mtd patchin script
#
VERSION=0
PATCHLEVEL=0
SUBLEVEL=0
COPYORLINK=$1
MULTIORSINGLE=$2
LINUXDIR=$3
# To be a Linux directory, it must have a Makefile
# shell函数应用:usage()函数显示如何使用
usage () {
echo "usage: $0 c/l m/s kernelpath"
echo " if c/l is c, then copy. If l then link"
echo " if m/s is m, then use multi version code. If s then use single version code"
exit 1
}
if [ -z $LINUXDIR ]
then
usage; //调用usage()函数
fi
if [ $COPYORLINK = l ]; then
CPY="ln -s"
elif [ $COPYORLINK = c ]; then
CPY="cp"
else
echo "unknown copy or link type"
usage;
fi
if [ $MULTIORSINGLE = m ]; then
VFS_CODE="yaffs_vfs_multi.c"
MTD_CODE="yaffs_mtdif_multi.c"
YPORTENV="yportenv_multi.h"
KCONFIG_SRC="Kconfig_multi"
elif [ $MULTIORSINGLE = s ]; then
VFS_CODE="yaffs_vfs_single.c"
MTD_CODE="yaffs_mtdif_single.c"
YPORTENV="yportenv_single.h"
KCONFIG_SRC="Kconfig_single"
echo ""
echo "*** Warning ***"
echo "You have chosen to use the single kernel variant of the yaffs VFS glue code"
echo "that only works with the latest Linux kernel tree. If you are using an older"
echo "version of Linux then you probably wanted to use the multi-version variant by"
echo "re-running the patch-ker.sh script using m as a the second argument."
echo " ie $0 $COPYORLINK m $LINUXDIR"
echo ""
else
echo "unknown multi/single version selection"
usage;
fi
# 判断Linux kernel根目录下是否有Makefile文件
if [ ! -f $LINUXDIR/Makefile ]
then
echo "Directory $LINUXDIR does not exist or is not a kernel source directory";
exit 1;
fi
# 获取内核版本
#sed s表示使用替换模式替换相应模式
VERSION=`grep -s VERSION <$LINUXDIR/Makefile | head -n 1 | sed s/'VERSION = '//` //查询成功后用//替换VERSION
PATCHLEVEL=`grep -s PATCHLEVEL <$LINUXDIR/Makefile | head -n 1 | sed s/'PATCHLEVEL = '//`
SUBLEVEL=`grep -s SUBLEVEL <$LINUXDIR/Makefile | head -n 1 | sed s/'SUBLEVEL = '//`
if [ $VERSION$PATCHLEVEL -lt 26 ]
then
echo "Cannot patch kernel version $VERSION.$PATCHLEVEL.$SUBLEVEL, must be 2.6.x or higher"
exit 1;
fi
KCONFIG=$LINUXDIR/fs/Kconfig
KCONFIGOLD=$LINUXDIR/fs/Kconfig.pre.yaffs
YAFFS_PATCHED_STRING=`grep -s yaffs <$KCONFIG | head -n 1`
MAKEFILE=$LINUXDIR/fs/Makefile
MAKEFILEOLD=$LINUXDIR/fs/Makefile.pre.yaffs
#判断是否存在yaffs?
if [ ! -z "$YAFFS_PATCHED_STRING" ]
then
YAFFS_PATCHED=0
echo "$KCONFIG already mentions YAFFS, so we will not change it"
else
# Change the fs/Kconfig file
# Save the old Kconfig
# Copy all stuff up to JFFS
# Insert some YAFFS stuff
# Copy all the rest of the stuff
#linux/fs不存在yaffs,则创建。
YAFFS_PATCHED=1
echo "Updating $KCONFIG"
mv -f $KCONFIG $KCONFIGOLD
sed -n -e "/[Jj][Ff][Ff][Ss]/,99999 ! p" $KCONFIGOLD >$KCONFIG
# echo "">>$KCONFIG
# echo "# Patched by YAFFS" >>$KCONFIG
echo "source \"fs/yaffs2/Kconfig\"">>$KCONFIG
# echo "">>$KCONFIG
sed -n -e "/[Jj][Ff][Ff][Ss]/,99999 p" $KCONFIGOLD >>$KCONFIG
# now do fs/Makefile -- simply add the target at the end
echo "Updating $MAKEFILE"
cp -f $MAKEFILE $MAKEFILEOLD
# echo "">>$MAKEFILE
# echo "# Patched by YAFFS" >>$MAKEFILE
echo "obj-\$(CONFIG_YAFFS_FS) += yaffs2/" >>$MAKEFILE
fi
YAFFSDIR=$LINUXDIR/fs/yaffs2
if [ -e $YAFFSDIR ]
then
echo "$YAFFSDIR exists, so not patching. If you want to replace what is"
echo "already there then delete $YAFFSDIR and re-run this script"
echo " eg. \"rm -rf $YAFFSDIR\" "
else
rm yaffs*.mod.c 2> /dev/null
mkdir $LINUXDIR/fs/yaffs2
$CPY $PWD/Makefile.kernel $LINUXDIR/fs/yaffs2/Makefile
$CPY $PWD/$KCONFIG_SRC $LINUXDIR/fs/yaffs2/Kconfig
$CPY $PWD/*.c $PWD/*.h $LINUXDIR/fs/yaffs2
rm $LINUXDIR/fs/yaffs2/yaffs_vfs*.c $LINUXDIR/fs/yaffs2/yaffs_mtdif*.c
rm $LINUXDIR/fs/yaffs2/yportenv*.h
rm $LINUXDIR/fs/yaffs2/moduleconfig.h
$CPY $PWD/$VFS_CODE $LINUXDIR/fs/yaffs2/yaffs_vfs.c
$CPY $PWD/$MTD_CODE $LINUXDIR/fs/yaffs2/yaffs_mtdif.c
$CPY $PWD/$YPORTENV $LINUXDIR/fs/yaffs2/yportenv.h
fi