实验:
以readdir为例
#include<sys/types.h>
#include<dirent.h>
#include<unistd.h>
main()
{
DIR * dir;
struct dirent * ptr;
int i;
dir =opendir(“/etc/rc.d”);
while((ptr = readdir(dir))!=NULL)
{
printf(“d_name: %s\n”,ptr->d_name);
}
closedir(dir);
}
//readdir()返回参数dir目录流的下个目录进入点。
结构dirent定义如下
struct dirent
{
ino_t d_ino;
ff_t d_off;
signed short int d_reclen;
unsigned char d_type;
har d_name[256;
};
d_ino 此目录进入点的inode
d_off 目录文件开头至此目录进入点的位移
d_reclen _name的长度,不包含NULL字符
d_type d_name 所指的文件类型
d_name 文件名
成功则返回下个目录进入点。有错误发生或读取到目录文件尾则返回NULL。
总结:
库函数封装系统函数
区分用户态和内核态
中断处理是从用户态进入内核态的主要方式
系统调用是一种特殊的中断
从用户态切换内核态时,要保存用户态寄存器上下文
中断int指令会在堆栈上保存寄存器当前的值
中断发生后第一件事是保存现场
保护现场进入中断程序保存需要用到的寄存器的数据
恢复现场退出中断程序恢复保存在寄存器的数据
中断处理的过程:
interrupt(ex:int 0x80) -save调用中断指令
cs:eip/ss:esp/eflags(current) to kernel stack 保存搁寄存器数据入栈
then load cs:eip(entry of a specific ISR) 调出中断服务地址指令入口
and ss:esp(point to kernel stack) 加载堆栈段
SAVE_ALL
//开始内核代码,完成中断服务,发生进程调度
RESTORE_ALL
iret - pop cs:eip/ss:esp/eflags from kernel stack 调出站内寄存器数据恢复现场
系统调用概述
系统调用为用户态进程与硬件设备进行交互提供接口
API和系统调用不同:
API只是一个函数定义
系统调用通过软中断想内核发出明确请求
Libc库封装系统调用例程
系统调用三层皮
xyz
system_call
sys_xyz
中断向量0x80与system_call绑定起来
系统调用号将xyz和sys_xyz关联起来
系统调用参数传递
入栈
fork()封装例程
王潇洋
原创作品转载请注明出处
《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000