Linux源码学习笔记:syscalls
来源:互联网 发布:淘宝网10至20包邮 编辑:程序博客网 时间:2024/06/01 22:51
最近一段时间,研究Linux源码,虽然断断续续的没有投入太多的时间,但也有不少收获。学习新知识的时候,一定要带着问题,不断的寻找答案。下面就是我在学习过程中整理的一些笔记,一开始不算完整,后面陆陆续续的不断补充。
我分析的源码是基于当前最新的3.16主版本。
1. 首先应该弄明白下面的一个问题:<unistd.h>具体引用的是哪个文件?相互之间的引用关系?
2. 以下这些系统调用的宏定义是怎么展开的?
SYSCALL_DEFINE0(...)
SYSCALL_DEFINE1(...)
SYSCALL_DEFINE2(...)
SYSCALL_DEFINE3(...)
SYSCALL_DEFINE4(...)
这些宏定义在:include/linux/syscalls.h文件中:
#define SYSCALL_DEFINE0(sname) \
SYSCALL_METADATA(_##sname, 0); \
asmlinkage long sys_##sname(void)
#define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)
#define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__)
#define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
#define SYSCALL_DEFINE4(name, ...) SYSCALL_DEFINEx(4, _##name, __VA_ARGS__)
#define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__)
#define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__)
#define SYSCALL_DEFINEx(x, sname, ...) \
SYSCALL_METADATA(sname, x, __VA_ARGS__) \
__SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
应用举例:
SYSCALL_DEFINE0(getxuid)
{
current_pt_regs()->r20 = sys_geteuid();
return sys_getuid();
}
SYSCALL_DEFINE0(getpid)
{
return task_tgid_vnr(current);
}
SYSCALL_DEFINE1(exit, int, error_code)
{
do_exit((error_code&0xff)<<8);
}
SYSCALL_DEFINE1(dup, unsigned int, fildes)
{
int ret = -EBADF;
struct file *file = fget_raw(fildes);
if (file) {
ret = get_unused_fd();
if (ret >= 0)
fd_install(ret, file);
else
fput(file);
}
return ret;
}
SYSCALL_DEFINE1(rmdir, const char __user *, pathname)
{
return do_rmdir(AT_FDCWD, pathname);
}
SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)
{
profile_munmap(addr);
return vm_munmap(addr, len);
}
SYSCALL_DEFINE2(dup2, unsigned int, oldfd, unsigned int, newfd)
{
if (unlikely(newfd == oldfd)) { /* corner case */
struct files_struct *files = current->files;
int retval = oldfd;
rcu_read_lock();
if (!fcheck_files(files, oldfd))
retval = -EBADF;
rcu_read_unlock();
return retval;
}
return sys_dup3(oldfd, newfd, 0);
}
SYSCALL_DEFINE2(kill, pid_t, pid, int, sig)
{
struct siginfo info;
info.si_signo = sig;
info.si_errno = 0;
info.si_code = SI_USER;
info.si_pid = task_tgid_vnr(current);
info.si_uid = from_kuid_munged(current_user_ns(), current_uid());
return kill_something_info(sig, &info, pid);
}
SYSCALL_DEFINE2(chmod, const char __user *, filename, umode_t, mode)
{
return sys_fchmodat(AT_FDCWD, filename, mode);
}
3. sys_call_table是怎么实现的?
作用应该是给每一个系统调用赋一个整数值作为系统调用号。这一个数组怎么和具体每一个系统调用函数关联起来的?
在文件<arch/score/kernel/sys_call_table.c>中有如下定义:
#undef __SYSCALL
#define __SYSCALL(nr, call) [nr] = (call),
void *sys_call_table[__NR_syscalls] = {
#include <asm/unistd.h>
};
而#include <asm/unistd.h>中又逐层的展开其他的unistd.h定义,主要是系统调用的消息号定义。
4. 理清楚不同体系结构的对应的系统调用号的引用关系?
和系统调用号有关的头文件主要有:
<arch/arm/include/uapi/asm/unistd.h>
<include/uapi/asm-generic/unistd.h>
arch目录下各个不同体系结构的系统调用号的定义不同。
5.
sys_ni_syscall() 除了返回ENOSYS以外什么也没有做,ENOSYS对应的错误是指当调用到一个无效的系统函数。但是为什么定义这么一个函数,我还是不太清楚,后续我再找人问问。
6. 系统调用函数通过0x80中断进行调用:
通过中断进行调用的方法的参数传递:功能号和返回值通过 %eax 来传递。
参数一般在5个以下的通过寄存器 %ebx,%ecx,%edx,%esi,%edi来传递,如果参数个数大于5个,则要通过堆栈来传递,按照c语言的参数传递方式,最后一个参数最先进栈。同时,把%esp传递给%ebx。
7.中段响应的入口函数:
代码在init/main.c文件:
asmlinkage __visible void __init start_kernel(void)
{
...
/*
* Set up the scheduler prior starting any interrupts (such as the
* timer interrupt). Full topology setup happens at smp_init()
* time - but meanwhile we still have a functioning scheduler.
*/
sched_init();
...
}
0 0
- Linux源码学习笔记:syscalls
- libuv中关于linux-syscalls和linux-inotify模块
- 在linux下调用syscalls.h头文件
- 在linux下调用syscalls.h头文件
- caffe源码与linux命令学习笔记
- linux 0.12 源码学习笔记(一)内核引导
- postgresql学习笔记【1】-Linux+eclipse+gdb调试postgresql源码
- Linux学习笔记(搭建本地源,源码安装)
- Linux学习笔记-----RPM包管理----源码包安装
- linux学习笔记(一) 源码和编译
- linux源码笔记
- linux softirq 源码 笔记
- Struts 源码学习笔记
- Struts 源码学习笔记
- NHibernate源码学习笔记
- TFTP源码 学习笔记
- Netty源码学习笔记
- FTP 源码学习笔记
- 一个简易的计算器程序
- vim之入门篇:安装/使用/配置
- VC使用: vs2003的工程升级到vs2010的问题汇总
- 最大权闭合子图的解法
- hdu 1171 Big Event
- Linux源码学习笔记:syscalls
- 一种快速的无监督的向量化方法做地标识别
- association 的使用
- ActiveX组件开发和使用
- HDU4920 Matrix multiplication (CPU cache对程序的影响)
- Python中的条件选择和循环语句
- rman configure命令
- mysql由浅入深视频-有高可用架构、调优、排错等
- const使用及问题总结