1. IO接口
接口:连接CPU和外设之间的部件,它完成CPU于外界的信息传送。还包括辅助CPU工作的外围电路,如中断控制器、DMA控制器、定时器、高速CACHE。
IO接口框图:
接口的十大功能:
- 输入输出功能
- 数据缓冲功能
- 联络功能
- 数据转换功能
- 中断管理功能
- 提供时序控制功能
- 寻址功能
- 可编程功能
- 电器特征的匹配功能
- 错误监测功能
2. 端口
端口的概念:
1. 软件上:接口中程序员可编程读写的寄存器地址。
2. 硬件上:接口电路中的寄存器等。
端口的分类:
1. 数据口:输入、输出的数据信息
2. 状态口:接口的状态
3. 控制口:控制信号
端口的读写操作(软件上)
1.读 IN
2.写 OUT
3.输入输出指令(IN,OUT):只限于使用AX或AL与外部设备的端口传送信息。
3. Unix I/O
一个Linux文件就是一个m字节的序列。
所有的I/O设备都被模型化为文件:
/dev/sda2(用户磁盘分区)
/dev/tty2(终端)
甚至内核也被映射为文件:
/boot/vmlinuz-3.13.0-55-generic(内核映像)
/proc(内核数据结构)
这种将设备优雅地映射为文件的方式,允许Linux内核引出一个简单、低级地应用接口,称为Unix I/O。
- 打开和关闭文件:open()和close()
- 读写文件:read()和write()
- 改变当前的文件位置(seek) lseek()
4. 文件类型
每个Linux文件都有一个类型来表明它在系统中的角色:
- 普通文件:包含任意数据
- 目录:一组链接文件的索引
- 套接字:用来与另一个进程进行跨网络通信
其它文件类型:命名通道、符号链接、字符和块设备。
普通文件
普通文件包含任意数据,应用程序常常要区分文本文件和二进制文件。
行结束标志:Linux和Mac(0xa \n) Windows(0xd 0xa \r \n)
目录
- 目录包含一组链接:每个链接将一个文件名映射到一个文件。
- 每个目录至少含有两个条目:.是到该文件自身的链接,..是到目录层次结构中父目录的链接。
- 操作目录命令:mkdir ls rmdir
5. 打开文件
打开文件是通知内核你准备好访问该文件。
int fd; /* file descriptor */
if ((fd = open("/etc/hosts", O_RDONLY)) < 0) {
perror("open");
exit(1);
}
返回一个小的描述符数字—文件描述符。返回的描述符总是在进程中当前没有打开的最小描述符。(fd=-1说明发生错误。)
Linux内核创建的每个进程都以与一个终端相关联的三个打开的文件开始:
- 0:标准输入(stdin)
- 1:标准输出(stdout)
- 2:标准错误(stderr)
6. 关闭文件
关闭文件是通知内核你要结束访问一个文件。
int fd; /* file descriptor */
int retval; /* return value */
if ((retval = close(fd)) < 0) {
perror("close");
exit(1);
}
关闭一个已经关闭的文件是导致线程程序灾难的一个因素。
7. 读文件
读文件从当前文件位置复制字节到内存位置,然后更新文件位置。
char buf[512];
int fd; /* file descriptor */
int nbytes; /* number of bytes read */
/* Open file fd ... */
/* Then read up to 512 bytes from file fd */
if ((nbytes = read(fd, buf, sizeof(buf))) < 0) {
perror("read");
exit(1);
}
返回值表示的是实际传送的字节数量。返回类型ssize_t是有符号整数;nbytes<0表示发生错误;不足值(short counts)是可能的,不是错误。
8. 写文件
写文件从内存复制字节到当前文件位置,然后更新文件位置。
char buf[512];
int fd; /* file descriptor */
int nbytes; /* number of bytes write */
/* Open the file fd ... */
/* Then write up to 512 bytes from buf to file fd */
if ((nbytes = write(fd, buf, sizeof(buf)) < 0) {
perror("write");
exit(1);
}
返回值表示从内存向文件fd实际传送的字节数量。
9. 用RIO包健壮地读写
RIO是一个封装类,在像网络程序这样容易出现不足值地应用中,提供了方便、健壮和高效地I/O。
RIO提供两类不同的函数
- 无缓冲的输入输出函数rio_readn和rio_written 每一字节都进内核
- 带缓冲的输入函数rio_readlineb和rio_readnb
10. 读取文件元数据
元数据是关于文件的信息。
每个文件的元数据都由内核来保存,用户通过stat和fstat函数访问元数据。