c - linux内核系统调用服务例程的源代码在哪里?
问题描述
我对系统调用(高级)工作流程的理解是:
- 用户调用 libc 包装器
- 包装器将系统调用号和参数放在正确的位置、寄存器或堆栈中
- 包装器执行系统调用或 int 0x80 指令
- 内核中断处理程序调用 sys_xxx() 服务程序
如果是这样,那么内核源代码中应该有一堆 sys_xxx() 函数。例如,对于read()
, 在内核 2.6 代码中,我找到了 sys_read。但是,在内核 5.4 代码中,我没有找到这样的服务例程代码,我发现的唯一sys_read就像 libc 包装器的替代品一样。所以我很困惑。。
一个相关的问题 - 内核将实现放在 sys_xxx() 中的原因是内核空间也可以调用这些函数,对吗?
解决方案
内核确实定义了一个名为的函数sys_read
,其行为如您所说。通过搜索很难找到它,因为它是通过使用标记连接的辅助宏定义的。见fs/read_write.c
第 595 行:
SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
{
return ksys_read(fd, buf, count);
}
这具有以下效果:
声明一个名为 的函数
sys_read
,别名为__se_sys_read
定义
__se_sys_read
,它显然对任何 32 位参数进行符号扩展,然后调用__do_sys_read
定义
__do_sys_read
谁的主体如图所示(即调用ksys_read
哪个执行实际工作)。
您可以在第 206 行看到SYSCALL_DEFINEx
宏的定义。include/linux/syscalls.h
推荐阅读
- oauth - 使用 Google 的 oauth2 服务交换访问令牌的授权码时出现 403
- wordpress - Divi Builder 在帖子类型上呈现 html 代码
- angular - Angular - 不记名令牌
- firebase - Firebase Auth - 自定义重定向域提示 NET::ERR_CERT_COMMON_NAME_INVALID 警告
- rdf - 上面的代码是将整个 fuseki 数据集加载到内存中还是保存在服务器端?
- ruby-on-rails - 视频处理:替换视频帧中的图像
- php - Outlook 的 PHPMailer 中的“SMTP 错误:无法验证”
- javascript - Angular mat-sidenav 未在 Safari(comp 或移动设备)上显示
- python - 将对象的 URL 转换为其数据库实例
- java - 消息源 Spring:NotSerializableException