5---Linux文件系统和设备文件系统

Linux文件操作

Linux文件操作涉及哪些系统调用?

创建、打开、读写和关闭文件

如何创建文件?

int creat(const char *filename, mode_t mode);

参数mode是什么含义?

参数mode 指定新建文件的存取权限,它同umask 一起决定文件的最终权限(mode&umask),

umask 是什么含义

代表了文件在创建时需要去掉的一些存取权限。

如何设置umask?

调用函数int umask(int newmask)将umask设置为newmask,然后返回旧的umask,它只影响读、写和执行权限。

打开文件的函数如何定义?

int open(const char *pathname, int flags);

参数pathname、flags是什么含义?

  • pathname是我们要打开的文件名(包含路径名称,默认在当前路径下)
  • flags表示打开的标志

打开的标志有哪些,是什么含义?

  • O_RDONLY 以只读的方式打开文件
  • O_WRONLY 以只写的方式打开文件
  • O_RDWR 以读写的方式打开文件
  • O_APPEND 以追加的方式打开文件
  • O_CREAT 创建一个文件
  • O_EXEC 如果使用了O_CREAT而且文件已经存在,就会发生一个错误
  • O_NOBLOCK 以非阻塞的方式打开一个文件
  • O_TRUNC 如果文件已经存在,则删除文件的内容

当flag为O_CREATE,对应使用哪个打开函数?

int open(const char *pathname,int flag,mode_t mode),实现了文件创建的功能

在上面的函数中,mode表示什么?

mode标志用来表示文件的访问权限

mode标志有哪些?

  • S_IRUSR 用户可以读
  • S_IWUSR 用户可以写
  • S_IXUSR 用户可以执行
  • S_IRWXU 用户可以读、写、执行
  • S_IRGRP 组可以读
  • S_IWGRP 组可以写
  • S_IXGRP 组可以执行
  • S_IRWXG 组可以读、写、执行
  • S_IROTH 其他人可以读
  • S_IWOTH 其他人可以写
  • S_IXOTH 其他人可以执行
  • S_IRWXO 其他人可以读、写、执行
  • S_ISUID 设置用户的执行ID
  • S_ISGID 设置组的执行ID

mode标志如何用数字来表示文件权限?

Linux 总共用5 个数字来表示文件的各种权限,每个数字可以取1(执行权限)、2(写权限)、4(读权限)、0(无)或者是这些值的和。

  • 第一位表示设置用户ID
  • 第二位表示设置组ID
  • 第三位表示用户自己的权限位
  • 第四位表示组的权限
  • 第五位表示其他人的权限

open("test", O_CREAT, 10705);
上述语句等价于:
open("test", O_CREAT, S_IRWXU | S_IROTH | S_IXOTH | S_ISUID );

读写函数如何定义?

int read(int fd, const void *buf, size_t length);
int write(int fd, const void *buf, size_t length);

读写函数的参数是什么含义?

参数fd文件描述符,buf为指向缓冲区的指针,length为缓冲区的大小(以字节为单位),返回值为实际读取和写入的字节数。

读写函数各完成什么功能?

  • read( )实现从文件描述符fd所指定的文件中读取length个字节到buf所指向的缓冲区中,返回值为实际读取的字节数
  • write( )实现将把length 个字节从buf 指向的缓冲区中写到文件描述符fd所指向的文件中,返回值为实际写入的字节数

如何定位文件,进行随机地指定位置读写?

int lseek(int fd, offset_t offset, int whence);

lseek()函数完成什么功能?

将文件读写指针相对whence移动offset(可取负值)个字节。操作成功时,返回文件指针相对于文件头的位置。

参数whence可以使用哪些值?

  • SEEK_SET:相对文件开头。
  • SEEK_CUR:相对文件读写指针的当前位置。
  • SEEK_END:相对文件末尾。

关闭函数int close(int fd)中fd指的是什么?

fd 是要关闭的文件描述符

C库函数的文件操作具有什么性质?

独立于具体的操作系统平台,不管是在DOS、Windows、Linux 还是在VxWorks中都是这些函数。

创建和打开文件的函数是什么?

FILE *fopen(const char *path, const char *mode);
fopen()实现打开指定文件filename,其中的mode为打开模式,Linux 系统不区分二进制文件和文本文件。

参数mode有哪些值?

  • r、rb 以只读方式打开
  • w、wb 以只写方式打开。如果文件不存在,则创建该文件,否则文件被截断
  • a、ab 以追加方式打开。如果文件不存在,则创建该文件
  • r+、r+b、rb+ 以读写方式打开
  • w+、w+b、wh+ 以读写方式打开。如果文件不存在,则创建新文件,否则文件被截断
  • a+、a+b、ab+ 以读和追加方式打开。如果文件不存在,则创建新文件

读写函数如何定义?

int fgetc(FILE *stream);
int fputc(int c, FILE *stream);
char *fgets(char *s, int n, FILE *stream);
int fputs(const char *s, FILE *stream);
int fprintf(FILE *stream, const char *format, ...);
int fscanf (FILE *stream, const char *format, ...);
size_t fread(void *ptr, size_t size, size_t n, FILE *stream);
size_t fwrite (const void *ptr, size_t size, size_t n, FILE *stream);
int fsetpos(FILE *stream, fpos_t *pos);
nt fsetpos(FILE *stream, const fpos_t *pos);
int fseek(FILE *stream, long offset, int whence);

读写函数完成什么功能?

  • fread()实现从stream中读取n 个字段,每个字段为size个字节,并将读取的字段放入ptr 所指的字符数组中,返回实际已读取的字段数。
  • fwrite()实现从缓冲区ptr 所指的数组中把n 个字段写到stream 中,每个字段长为size个字节,返回实际写入的字段数。

关闭函数如何定义?

int fclose (FILE *stream);

Linux文件系统

Linux文件系统目录结构是什么样的?

003vPl7Rty6E8kZRlAEdc&690

  • /bin----存放着最经常使用的基本命令,如ls、cp、mkdir 等,这个目录中的文件都是可执行的。
  • /boot----启动Linux时使用的一些核心文件,包括一些连接文件以及镜像文件,如vmlinuz、initrd.img 
  • /dev----设备文件存储目录,应用程序通过对这些文件的读写和控制就可以访问实际的设备。
  • /etc----系统管理所需要的配置文件和子目录,如用户账号及密码配置文件。
  • /home----普通用户的家目录,每个用户都有一个自己的目录,一般该目录名是以用户的账号命名的。
  • /lib----库文件存放目录,系统最基本的动态连接共享库,类似于Windows里的DLL文件。
  • /lost+found----一般情况下是空的,当系统意外崩溃或机器意外关机时会产生一些文件碎片放在这里。
  • /mnt----方便用户临时挂载别的文件系统的,如将光驱挂载在/mnt/上,进入该目录就可以查看光驱里的内容
  • media----自动识别一些设备挂载到这个目录下,例如U盘、光驱等等。
  • /opt----给主机额外安装软件所存放的目录
  • /proc----操作系统运行时,进程及内核信息(比如CPU、硬盘分区、内存信息等)存放在这里。它是系统内存的映射,存在在内存,通过直接访问这个目录来获取系统信息。
  • /root----超级权限用户的家目录
  • /sbin----超级权限用户的可执行命令存放目录,普通用户无权限执行这个目录下的命令
  • /tmp-----存放临时文件。
  • /usr-----系统应用程序和文件(如命令、帮助文件)存放程序的目录,类似于windows下的program files目录。
  • /var-----经常被修改的目录放在这个目录下,如日志文件
  • /sys----内核设备树的一个直观反映。当一个内核对象被创建的时候,对应的文件和目录也在内核对象子系统中被创建。
  • /initrd---若在启动过程中使用了initrd 映像作为临时根文件系统,则在执行完其上的/linuxrc挂接真正的根文件系统后,原来的初始RAM文件系统被映射到/initrd目录。

Linux 系统中虚拟文件系统、磁盘文件(存放于RamDisk、Flash、ROM、SD 卡、U 盘等文件系统中的文件也属于磁盘文件)及一般的设备文件与设备驱动程序之间有什么关系?

  • 应用程序和VFS 之间的接口是系统调用
  • VFS 与磁盘文件系统以及普通设备之间的接口是file_operations结构体成员函数,这个结构体包含对文件进行打开、关闭、读写、控制的一系列成员函数。

字符设备的file_operations 成员函数由谁来提供?

由于字符设备的上层没有磁盘文件系统,所以字符设备的file_operations 成员函数就直接由设备驱动提供了,file_operations 正是字符设备驱动的核心。

在设备驱动程序的设计中,一般而言,关心什么?

关心file和inode这两个结构体。

file结构体有什么作用?

file文件结构体代表一个打开的文件(设备对应于设备文件),系统中每个打开的文件在内核空间都有一个关联的struct file。

file结构体什么时候创建,什么时候结束? 

它由内核在打开文件时创建,并传递给在文件上进行操作的任何函数。在文件的所有实例都关闭后,内核释放这个数据结构。

 如何定义文件结构体?

1 struct file
2 {
3 union
4 {
5 struct list_head fu_list;
6 struct rcu_head fu_rcuhead;
7 } f_u;

8 struct dentry *f_dentry; /*与文件关联的目录入口(dentry)结构*/
9 struct vfsmount *f_vfsmnt;
10 struct file_operations *f_op; /* 和文件关联的操作*/
11 atomic_t f_count;
12 unsigned int f_flags; /*文件标志,如O_RDONLY、O_NONBLOCK、O_SYNC*/
13 mode_t f_mode; /*文件读/写模式,FMODE_READ和FMODE_WRITE*/
14 loff_t f_pos; /* 当前读写位置*/
15 struct fown_struct f_owner;
16 unsigned int f_uid, f_gid;
17 struct file_ra_state f_ra;
19 unsigned long f_version;
20 void *f_security;

22 /* tty驱动需要,其他的驱动可能需要*/
23 void *private_data; /*文件私有数据*/

25 #ifdef CONFIG_EPOLL
26 /* 被fs/eventpoll.c使用以便连接所有这个文件的钩子(hooks) */
27 struct list_head f_ep_links;
28 spinlock_t f_ep_lock;
29 #endif /* #ifdef CONFIG_EPOLL */

30 struct address_space *f_mapping;
31 };

如何检测用户打开文件的读写方式?

if (file->f_mode & FMODE_WRITE) //用户要求可写
{
}
if (file->f_mode & FMODE_READ) //用户要求可读
{
}

如何判断以阻塞还是非阻塞方式打开设备文件?

if (file->f_flags & O_NONBLOCK) //非阻塞
pr_debug("open: non-blocking\n");
else //阻塞
pr_debug("open: blocking\n");

VFS inode 包含哪些信息?

文件访问权限、属主、组、大小、生成时间、访问时间、最后修改时间等信息。

VFS inode有什么作用?

它是Linux 管理文件系统的最基本单位,也是文件系统连接任何子目录、文件的桥梁。

如何定义inode结构体?

struct inode
2 {
3 ...
4 umode_t i_mode; /* inode的权限*/
5 uid_t i_uid; /* inode拥有者的id */
6 gid_t i_gid; /* inode所属的群组id */
7 dev_t i_rdev; /* 若是设备文件,此字段将记录设备的设备号*/
8 loff_t i_size; /* inode所代表的文件大小*/

10 struct timespec i_atime; /* inode最近一次的存取时间*/
11 struct timespec i_mtime; /* inode最近一次的修改时间*/
12 struct timespec i_ctime; /* inode的产生时间*/

14 unsigned long i_blksize; /* inode在做I/O时的区块大小*/
15 unsigned long i_blocks; /* inode 所使用的block 数,一个block 为512byte*/

17 struct block_device *i_bdev;
18 /*若是块设备,为其对应的block_device结构体指针*/
19 struct cdev *i_cdev; /*若是字符设备,为其对应的cdev结构体指针*/
20 ...
21 };

如何从一个inode中获得主设备号和次设备号?

unsigned int iminor(struct inode *inode);//获得次设备号
unsigned int imajor(struct inode *inode);//获得主设备号

如何获知系统中注册的设备?

查看/proc/devices 文件

如何获知系统中包含的设备文件?

查看/dev目录,日期的前两列给出了对应设备的主设备号和次设备号。

主设备号的作用是什么?

主设备号是与驱动对应的概念,同一类设备一般使用相同的主设备号,不同类的设备一般使用不同的主设备号(但是也不排除在同一主设备号下包含有一定差异的设备)。

次设备号的作用是什么?

因为同一驱动可支持多个同类设备,因此用次设备号来描述使用该驱动的设备的序号,序号一般从0 开始。

devfs 设备文件系统

devfs设备文件系统有什么作用?

使得设备驱动程序能自主地管理它自己的设备文件

devfs设备文件系统有什么优点?

  • 可以通过程序在设备初始化时在/dev目录下创建设备文件,卸载设备时将它删除。
  • 设备驱动程序可以指定设备名、所有者和权限位,用户空间程序仍可以修改所有者和权限位。
  • 不再需要为设备驱动程序分配主设备号以及处理次设备号,在程序中可以直接给register_chrdev()传递0 主设备号以动态获得可用的主设备号,并在devfs_register()中指定次设备号。

驱动程序如何进行设备文件的创建和删除工作?

/*创建设备目录*/
devfs_handle_t devfs_mk_dir(devfs_handle_t dir, const char *name, void*info);
/*创建设备文件*/
devfs_handle_t devfs_register(devfs_handle_t dir, const char *name,unsigned int flags, unsigned int major, unsigned int minor, umode_t mode, void*ops,void *info);
/*撤销设备文件*/
void devfs_unregister(devfs_handle_t de);

如何使用devfs 进行完整的操作?

1 static devfs_handle_t devfs_handle;
2 static int _ _init xxx_init(void)
3 {
4 int ret;
5 int i;
6 /*在内核中注册设备*/
7 ret = register_chrdev(XXX_MAJOR, DEVICE_NAME, &xxx_fops);
8 if (ret < 0)
9 {
10 printk(DEVICE_NAME " can't register major number\n");
11 return ret;
12 }
13 /*创建设备文件*/
14 devfs_handle =devfs_register(NULL, DEVICE_NAME,DEVFS_FL_DEFAULT, XXX_MAJOR, 0, S_IFCHR | S_IRUSR | S_IWUSR, &xxx_fops, NULL);
16 ...
17 printk(DEVICE_NAME " initialized\n");
18 return 0;
19 }
20
21 static void _ _exit xxx_exit(void)
22 {
23 devfs_unregister(devfs_handle); /*撤销设备文件*/
24 unregister_chrdev(XXX_MAJOR, DEVICE_NAME); /*注销设备*/
25 }
26
27 module_init(xxx_init);
28 module_exit(xxx_exit);

udev 设备文件系统

udev 设备文件系统的工作机制是什么?

  • udev 利用设备加入或移除时内核所发送的热插拔事件(hotplugevent)来进行设备文件的创建和删除等。在热插拔时,设备的详细信息会由内核输出到位于/sys的sysfs文件系统,同时,/dev目录下只包含系统中真正存在的设备
  • udev的设备命名策略、权限控制和事件处理都是在用户态下完成的,利用sysfs中的信息来进行创建设备文件节点等工作。

什么是sysfs 文件系统?

sysfs 被看成是与proc、devfs 和devpty 同类别的文件系统,该文件系统是一个虚拟的文件系统,它可以产生一个包括所有系统
硬件的层级视图,与提供进程和状态信息的proc文件系统十分类似。

sysfs 文件系统有什么作用?

  • 把连接在系统上的设备和总线组织成为一个分级的文件,它们可以由用户空间存取,向用户空间导出内核数据结构以及它们的属性
  • 展示设备驱动模型中各组件的层次关系,其顶级目录包括block、device、bus、drivers、class、power 和firmware。

Linux 2.6内核的设备模型是怎样的?

内核怎样完成设备模型的架构?

借助kobject、kset、subsystem、bus_type、device、device_driver、class、class_device、class_interface 等重量级数据结构来完成。

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值