5.1 Linux文件操作
- Linux的文件操作系统调用涉及创建、打开、读写、关闭。
- 创建:int creat(const char *filename, mode_t mode)
- 打开:
- int open(const char *pathname, int flags);
- int open(const char *pathname, int flags, mode_t mode);
- fiags文件打开标志
- 文件访问权限
- fiags文件打开标志
- 文件打开成功,open函数会返回一个文件描述符
- Linux用5个数字来表示文件的各种权限:第一位表示设置用户ID;第二位表示设置组ID;第三位表示用户自己的权限位;第四位表示组的权限;最后一位表示其他人的权限。
- 读写:
- 读:int read(int fd, const void *buf, size_t length);
返回值为实际读取字节数 - 写:int write(int fd, const void *buf, size_t length);
返回值为实际写入字节数
- 读:int read(int fd, const void *buf, size_t length);
- 定位:int lseek(int fd, offset_t offset, int whence);
- 关闭:int close(int fd);
- C库文件操作:fopen、fread、write、fclose等
5.2 Linux文件系统
- 文件系统结构目录
- /bin包含基本命令,如ls、cp、mkdir等,这个目录中的文件都是可执行的。
- /sbin包含系统命令,如modprobe、hwclock、ifconfig等,大多是涉及系统管理的命令,这个目录中的文件都是可执行的。
- /dev设备文件存储目录,应用程序通过对这些文件的读写和控制以访问实际的设备。
- /etc系统配置文件的所在地,一些服务器的配置文件也在这里,如用户账号及密码配置文件。busybox的启动脚本也存放在该目录。
- /lib系统库文件存放目录等
- /mnt这个目录一般是用于存放挂载储存设备的挂载目录
- /optopt是“可选”的意思,有些软件包会被安装在这里
- /proc操作系统运行时,进程及内核信息(比如CPU、硬盘分区、内存信息等)存放在这里。/proc目录为伪文件系统proc的挂载目录,proc并不是真正的文件系统,它存在于内存之中。
- /usr这个是系统存放程序的目录,比如用户命令、用户库等
- /tmp用户运行程序的时候,有时会产生临时文件,/tmp用来存放临时文件。
- /var表示的是变化的意思,这个目录的内容经常变动,如/var的/var/log目录被用来存放系统日志
- /sys Linux设备驱动模型中的总线、驱动和设备都可以在sysfs文件系统中找到对应的节点。当内核检测到在系统中出现了新设备后,内核会在sysfs文件系统中为该新设备生成一项新的记录。
- Linux文件系统与设备驱动
应用和VFS(虚拟文件系统)接口为系统调用,VFS与文件系统设备文件接口是file_operations结构体成员函数。 - 块设备的访问:
- 直接访问裸设备
- 通过文件系统
- file结构体:由内核打开文件时创建:f_mode、f_flags、private_data等为该结构体的成员变量
- inode结构体:包含文件访问权限、属主、组、大小、生成时间、访问时间、最后修改时间等
- 设备号类型dev_t,高12位为主设备号,低20位为次设备号
- 可以通过查看 /proc/devices文件获知已注册的设备
- 查看 /dev可以获知系统中包含的设备文件
- 同一类设备一般主设备号相同
- 序号一般从0开始
5.3 devfs(设备文件系统)
- Linux 2.4引入,使设备驱动程序能自主管理自己的设备文件
- devfs的优点:
- 程序在设备初始化时在 /dev目录下创建设备文件,卸载时删除
- 设备驱动程序可以指定设备名、所有者和权限位,用户空间程序仍可以修改所有者和权限位。
- 不再需要为设备驱动程序分配主设备号以及处理次设备号
5.4 udev用户空间设备管理
- udev在2.6内核版本代替了devfs,是一种工作在用户态的用户程序
- devfs工作在内核态,udev完全在用户态工作,利用设备加入或移除时内核所发送的热插拔事件来工作
- 采用devfs,当一个并不存在的/dev节点被打开的时候,devfs能自动加载对应的驱动,而udev则不这么做。这是因为udev的设计者认为Linux应该在设备被发现的时候加载驱动模块,而不是当它被访问的时候。
- sysfs是3.6版本引入的虚拟文件系统,可以产生一个包括所有系统硬件的层级视图,展示设备驱动模型中各组件的层次关系。
- 在include/linux/device.h中用 bus_type、device_driver、device 描述总线、驱动和设备。
- device_driver和device分别表示驱动和设备,二者必须依附于一种总线,都包含struct bus_type指针。
- 设备和驱动时分开注册的(有设备不一定有驱动,反之亦然),二者通过bus_type的match()函数进行匹配,匹配成功后,xxx_driver中的probe()函数就会被执行。
- 工作机制:
- 系统检测到新设备后,内核会通过netlink套接字发送uevent
- udev获取内核发送的信息,进行规则的匹配。
- 匹配关键字:ACTION(行为)、KERNEL(匹配内核设备名)、BUS(总线类型)、SUBSYSTEM(子系统)、ATTR(属性)
- 可以借助udev中的udevadm info工具查找规则文件能利用的内核信息和sysfs属性信息
- 如果/dev/下面的节点已经被创建,但是不知道它对应的/sys具体节点路径,可以采用“udevadm info-a-p$(udevadm info-q path-n/dev/<节点名>)”命令反向分析
- mdev是busybox中udev的轻量级版本,vold是安卓中的