一.源代码分析:
mknod-系统调用-
/fs/namei.c
syscall_define3(mknod,const char __user *,filename,int,mode,unsigned,dev ) )。
{
returnsys_mknodat(at_FDCWD,filename,mode,dev );
}
syscall_define4(mknodat,int,dfd,const char __user *,filename,int,mode,unsigned,dev ) )
{
输入错误;
char *tmp;
struct dentry *dentry;
struct nameidata nd;
.
error=user_path_parent(DFD,filename,nd,tmp );
.
dentry=lookup_create(nd,0 );
.
if (! is _ POSIX ACL (nd.path.dentry-d _ inode ) ) mode=~current_umask );
error=may_mknod(mode;
.
error=mnt _ want _ write (nd.path.mnt );
.
error=security _ path _ mknod (nd.path,dentry,mode,dev );
.
sitch(modes_ifmt ) )为
{
case 0: case S_IFREG:
error=VFS _ create (nd.path.dentry-d _ inode,dentry,mode,nd );
黑;
cases _ if chr : cases _ if blk :
error=VFS _ mknod (nd.path.dentry-d _ inode、dentry、mode、new_decode_dev );
黑;
cases _ ififo : cases _ if sock :
error=VFS _ mknod (nd.path.dentry-d _ inode,dentry,mode,0 );
黑;
}
.
}
使用new_decode_dev(dev )创建设备编号
staticinlinedev _ tnew _ decode _ dev (u 32 dev ) )。
{
unsignedmajor=(dev0xfff00 ) 8;
unsignedminor=(dev0xff )|) )0xfff00;
returnmkdev(major,minor );
}
includelinuxtypes.h
typedef __kernel_dev_tdev_t;
typedef__u32__kernel_dev_t;
vfs_create (:用于创建常规文件
vfs_mkdir (:用于创建目录节点
用于创建vfs_mknod (:特殊文件(FIFO、套接字、字符设备文件、块设备文件)
/proc目录中的特殊文件由内核生成,并且由非用户创建。
intVFS_mknod(structinode*dir,struct dentry *dentry,int mode,dev_t dev ) )
{
interror=may_create(dir,dentry;
.
if((s_ischr )模式)! ns_capable(inode_userns(dir ),CAP_MKNOD ) ) return -EPERM;
.
error=dev cgroup _ inode _ mknod (mode,dev );
error=security_inode_mknod(dir,dentry,mode,dev );
error=dir-I_op-mknod(dir,dentry,mode,dev );
.
}
DIR :指向要为其创建设备文件的父节点的innode结构指针。 由path_walk ()检测到。
dentry :表示要创建的设备的文件节点的目录条目dentry结构。 sys_mknod中的lookup_create是在内核dentry结构哈希表中搜索或创建的
vfs_mknod是虚拟文件系统的mknod
其次,有与struct inode _ operations jfs _ dir _ inode _ operations对应的实际文件系统,如ext2、ext3、ext4、jffs和yaffs
的. mknod=jfs_mknod,
staticintjfs _ mknod (struct inode * dir,struct dentry *dentry,int mode,dev_t rdev ) ) ) ) ) ) ) )
{
.
struct inode *ip;
.
IP=Ialloc(dir,mode );
.
init_special_inode(IP,ip-i_mode,rdev );
.
}
ialloc分配inode结构,并填充init_special_inode
/fs/inode.c
void init _ special _ inode (struct inode * inode,umode_t mode,dev_t rdev ) )。
{
inode-i_mode=mode;
if(s_ischr(mode ) )//字符设备
{
inode-i_fop=def_chr_fops;
inode-i_rdev=rdev;
}
elseif(s_isblk )模式)//块设备
{
inode-i_fop=def_blk_fops;
inode-i_rdev=rdev;
}
elseif(s_isFIFO )模式)//FIFO流媒体设备
inode-i_fop=def_fifo_fops;
ELSEif(s_issock )模式)//网络设备
inode-i_fop=bad_sock_fops;
else//未知设备提示
printk (kern _ debug ' init _ special _ inode : bogusi _ mode (% o ) for inode %s:%lun )、mode、inode
}
export _ symbol (init _ special _ inode;
函数设置file_operaTIon的i_fop和设备编号i_rdev