目录
1.Linux文件系统操作
Linux文件创建,打开,关闭函数
Linux下文件读写函数
2.C库文件操作
3.Linux文件系统
3.1根目录结构
3.2.VFS
VFS 虚拟文件系统基础概念
Linux文件系统与设备驱动关系:
设备驱动结构体:file,inode
inode结构体
inode之atime,mtime,ctime
file结构体
3.3 sysfs文件系统
3.4 udev规则文件
1.Linux文件系统操作
Linux文件创建,打开,关闭函数
#文件权限最终由mode&umask决定
int creat (const char *filename,mode_t mode); //文件创建
int umask(int newmask); //修改文件权限
int open (const char *filename,int flags); //文件打开
int open (const char *filename,int flags,mode_t mode); //文件打开
int close (int fd);//fd=open(......)//文件关闭函数
其中 flag可为以下一个或组合:(当flags含O_CREAT时,open函数相当于创建文件函数)
mode为以下一个或组合:
当然mode也可以用数字表示,方法如下:
权限数字含义:
数字含义
1
2
4
0
执行权限
写权限
读权限
无权限
文件权限各位含义(10705为例):
位数
第一位
第二位
第三位
第四位
第五位
作用
设置用户ID
设置组ID
用户权限
组权限
其他人权限
1
0
7(1+2+4)
0
5(1+4)
设置
不设置
执行;读;写
无权限
读;执行
因此10705等价与S_IRWXU|S_IROTH|SIXOTH|S_ISUID
文件打开后,就要对文件进行
读写
Linux下文件读写函数
int read(int fd,const void *buf,size_t length);
int write(int fd,const void *buf,size_t length);
指定位置读写:
nt lseek(int fd,offset_t offset,int whence);
lseek()将文件读写指针相对whence移动offset个字节,函数返回文件指针相对头问价的偏移量
SEEK_SET
相对文件开头
SEEK_CUR
相对文件读写指针的当前位置
SEEK_END
相对文件末尾
2.C库文件操作
利用标准C语言库进行文件读写
3.Linux文件系统
3.1根目录结构
目录
应放置档案内容
/bin
系统有很多放置执行档的目录,但/bin用于存放基本命令,单用户模式下也能运行.
/boot
主要放置开机会使用到的档案,包括Linux核心档案以及开机选单与开机所需设定档等等。Linux kernel常用的档名为:vmlinuz ,如果使用的是grub这个开机管理程式,则还会存在/boot/grub/这个目录。
/dev
设备文件存储目录,应用程序通过对此目录下文件读写和控制以访问实际设备
/etc
系统配置文件所在地,一些服务器的配置文件也在这里,如用户账户及密码配置文件
/home
这是系统预设的使用者家目录(home directory)。 在你新增一个一般使用者帐号时,预设的使用者家目录都会规范到这里来。
/lib
系统库文件存放目录,其下的/lib/modules/目录,放置核心相关的模组(驱动程式)。
/media
media是媒体的英文,这个/media底下放置的就是可移除的装置。 包括软碟、光碟、DVD等等装置都暂时挂载于此
/mnt
挂载储存设备的目录
/opt
可选的意思,有些软件被安装在这里
/root
系统管理员(root)的家目录。 因此即使单用户模式下仅仅挂在根目录,也能访问root目录
/sbin
Linux有非常多指令是用来设定系统环境的,这些指令只有root才能够利用来设定系统,其他使用者最多只能用来查询而已。放在/sbin底下的为开机过程中所需要的,里面包括了开机、修复、还原系统所需要的指令。至于某些伺服器软体程式,一般则放置到/usr/sbin/当中。至于本机自行安装的软体所产生的系统执行档(system binary),则放置到/usr/local/sbin/当中了。常见的指令包括:fdisk, fsck, ifconfig, init, mkfs等等。
/srv
srv可以视为service的缩写,是一些网路服务启动之后,这些服务所需要取用的资料目录。 常见的服务例如WWW, FTP等等。 举例来说,WWW伺服器需要的网页资料就可以放置在/srv/www/里面。呵呵,看来平时我们编写的代码应该放到这里了。
/tmp
这是让一般使用者或者是正在执行的程序暂时放置档案的地方。这个目录是任何人都能够存取的,所以你需要定期的清理一下。当然,重要资料不可放置在此目录啊。 因为FHS甚至建议在开机时,应该要将/tmp下的资料都删除。
/proc
这个目录本身是一个虚拟文件系统(virtual filesystem),它存在于内存中。 操作系统运行时,进程以及内核信息(比如CPU,硬盘分区,内存信息等)存放在这里.他放置的资料都是在内存当中,
/sys
2.6以后内核所支持的sysfs文件系统被映射在此处
/tmp
用户运行时产生的临时文件,/tmp用来用来存储临时文件
/usr
系统存放程序的目录,比如用户命令,用户库
/var
这个目录的内容经常变动,比如/var/log 存放系统日志
3.2.VFS
VFS 虚拟文件系统基础概念
Linux 允许众多不同的文件系统共存,并支持
跨文件系统的文件操作,这是因为有虚拟文件系统的存在。虚拟文件系统,即
VFS(Virtual File System)是 Linux 内核中的一个软件抽象层。它通过一些数据结构及其方法向实际的文件系统如 ext2,vfat 提供接口机制。
Linux文件系统与设备驱动关系:
可以看到
字符设备上层没有类似ext2的文件系统,所以访问
字符设备的file_operations成员函数直接由
字符设备驱动提供
块设备访问方法有两种:
- 不通过文件系统直接访问裸设备
- 通过文件系统访问,file_operations的实现位于文件系统,文件系统把针对文件的读写,转换为针对块原始扇区的读写
设备驱动结构体:file,inode
Linux字符设备中的两个重要结构体(file、inode),含源代码
Linux inode理解
inode结构体
文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector)。每个扇区储存512字节(相当于0.5KB)操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个"块"(block)。这种由多个扇区组成的"块",是文件存取的最小单位。"块"的大小,最常见的是4KB,即连续八个 sector组成一个 block。
文件数据都储存在"块"中,那么很显然,我们还必须找到一个地方储存文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。
这种储存文件元信息的区域就叫做inode,中文译名为"索引节点"。
inodo中包括的内容如下:(总之,
除了文件名以外的所有文件信息,都存在inode之中。至于为什么没有文件名,下文会有详细解释。)
- 文件字节数
- 文件拥有者ID
- 文件的Group ID
- 文件的读写执行权限
- 文件的时间戳(ctime指inode上一次变动的时间,mtime指文件内容上一次变动的时间,atime指文件上一次打开的时间)
- 链接数,即有多少个文件名指向这个inode
- 文件数据block位置
用stat命令查看文件的inode信息,如下:
inode之atime,mtime,ctime
时间戳
解释
备注
Access
(atime)
在终端上用cat、more 、less、grep、sed、 cp 、file 一个文件时,此文件的Access的时间记录都会被更新(空文件例外),纯粹的access是不会影响modify和change,但会受到modify行为的影响。
ls等命令访问后时间也更新
Modify
(mtime)
当更改了一个文件的内容的时候,此文件的modify的时间记录会被更新。用ls -l看到的文件时间是最近一次modify的时间。modify的行为是三个行为中最有影响力的行为,它发生以后,会使文件的access记录与change记录也同时得到更新。对于目录也是如此。
更改数据后更新,但是拷贝,剪切等操作不会更新该时间
change
(ctime)
对一个文件或者目录作mv、chown、chgrp操作后,它的Change时间记录被更新,change时间会受到modify行为的影响。用ls -lc看到的文件时间是最近一次change的时间。
拷贝等操作后更新,mtime,atime更新后,change也会更新
file结构体
在设备驱动中,这也是个非常重要的数据结构,必须要注意一点,这里的file与用户空间程序中的FILE指针是不同的,用户空间FILE是定义在C库中,从来不会出现在内核中。
而struct file,却是内核当中的数据结构,因此,它也不会出现在用户层程序中。
file结构体指示一个已经打开的文件(设备对应于设备文件),其实系统中的每个打开的文件在内核空间都有一个相应的struct file结构体,它由内核在打开文件时创建,并传递给在文件上进行操作的任何函数,直至文件被关闭。如果文件被关闭,内核就会释放相应的数据结构。
在内核源码中,struct file要么表示为file,或者为filp(意指“file pointer”), 注意区分一点,file指的是struct file本身,而filp是指向这个结构体的指针。
3.3 sysfs文件系统
打开终端,在/sys目录下,用命令tree打印树形目录
可以发现/sys结构可以描述如下:
设备存储在/sys/devices目录下,而诸如总线(bus),类(class)下的设备,实际只是链接,最终 链接到/sysy/devices下的设备
3.4 udev规则文件
udev规则采用行为单位,每一行代表一个规则,每个规则分为一个或多个匹配部分和赋值部分.
匹配关键词包括:
ACTION:
事件行为,例如:add remove
KERNEL:
内核设备名,例如:sda,ttyUSB*
DEVPATH:
设备的devpath路径,
SUBSYSTEM:
设备的子系统名称,例如sda的子系统为block
BUS:
设备在devpath中的总线名称,例如:USB
DRIVER:
设备在devpath中的设备驱动名称,例如ide-cdrom
SYSFS{filename}
设备的devpath路径下,设备的属性文件"filename"中的内容
ENV{key}:
环境变量。在一条规则中,可以设定最多五条环境变量的 匹配键。
PROGRAM:
调用外部命令。
RESULT:
外部命令 PROGRAM 的返回结果。
ATTR:
ATTRS - 匹配设备的sysfs属性,或任何双亲设备的sysfs属性 ,例如:ATTR{size},ATTR{address}
注意:
devpath:devpath是指一个设备在sysfs文件系统(/sys)下的相对路径,该路径包含了指定设备的属性文件。udev里的多数命令都是针对devpath操作的。例如:sda的devpath是/block/sda,sda2的devpath是/block/sda/sda2
udev的重要赋值键:
NAME:
在 /dev下产生的设备文件名。只有第一次对某个设备的 NAME 的赋值行为生效,之后匹配的规则再对该设备的 NAME 赋值行为将被忽略。如果没有任何规则对设备的 NAME 赋值,udev 将使用内核设备名称来产生设备文件。
SYMLINK:
为 /dev/下的设备文件产生符号链接。由于 udev 只能为某个设备产生一个设备文件,所以为了不覆盖系统默认的 udev 规则所产生的文件,推荐使用符号链接。
OWNER, GROUP, MODE:
为设备设定权限。
udev 的值和可调用的替换操作符
Linux 用户可以随意地定制 udev 规则文件的值。例如:my_root_disk, my_printer。同时也可以引用下面的替换操作符:
$kernel, %k:设备的内核设备名称,例如:sda、cdrom。
$number, %n:设备的内核号码,例如:sda3 的内核号码是 3。
$devpath, %p:设备的 devpath路径。
$id, %b:设备在 devpath里的 ID 号。
$sysfs{file}, %s{file}:设备的 sysfs里 file 的内容。其实就是设备的属性值。
$env{key}, %E{key}:一个环境变量的值。
$major, %M:设备的 major 号。
$minor %m:设备的 minor 号。
$result, %c:PROGRAM 返回的结果。
$parent, %P:父设备的设备文件名。
$root, %r:udev_root的值,默认是 /dev/。
$tempnode, %N:临时设备名。
%%:符号 % 本身。
$$:符号 $ 本身。
例子:
添加串口线,根据芯片自动绑定对应串口别名,参考博客
USB hub 多usb接口重映射:udev 规则