The asmlinkage tag is one other thing that we should observe aboutthis simple function. This is a #define for some gcc magic that tellsthe compiler that the function
should not expect to find any of itsarguments in registers (a common optimization),
but only on theCPU’s stack. Recall our earlier assertion that system_call consumesits
first argument, the system call number, and allows up to four morearguments that are
passed along to the real system call. system_callachieves this feat simply by leaving its other
arguments (which werepassed to it in registers) on the stack. All system calls are markedwith
the asmlinkage tag, so they all look to the stack for arguments.Of course, in sys_ni_syscall’s case,
this doesn’t make any difference,because sys_ni_syscall doesn’t take any arguments, but it’s an
issuefor most other system calls. And, because you’ll be seeingasmlinkage in front of many other
functions, I thought you shouldknow what it was about.
而我在 2.6.8的内核上的include/linux/linkage.h查到它的定义是:
#ifndef asmlinkage
#define asmlinkage CPP_ASMLINKAGE
#endif
进一步,CPP_ASMLINKAGE的定义为:
#ifdef __cplusplus
#define CPP_ASMLINKAGE extern “C”
#else
#define CPP_ASMLINKAGE
#endif
而在include/asm-i386/linkage.h里则有更明确的定义:
#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
__attribute__是GCC的C语言扩展语法。regparm(0)表示不从寄存器中传递参数。
另外,如果是__attribute__((regparm(3))),那么调用函数的时候参数不是通过栈传递,而是直接放到寄存器里,被调用函数直接从寄存器取参数。
此句引自了海中一浪的博客文章
asmlinkage确保它定义的函数从栈中读取参数而不是在寄存器中。
分享到:
相关推荐
#### 一、asmlinkage宏 在阅读Linux内核源码的过程中,我们经常会遇到一个名为`asmlinkage`的宏。它主要用于标记那些需要通过栈来传递参数的函数,而不是通过寄存器传递。这对于理解系统调用的实现机制具有重要的...
系统调用接口调用“int $Ox8O”指令进入内核并准各了相关参数后,剩下的工作就由系统调用例程来进行。Linux定义的系统调用 例程的入口为system_call。下面具体介绍system_call所做的工作。 system_call是用汇编...
最后,需要在 `syscalls.h` 中添加一个新的系统调用声明,例如 `asmlinkage long sys_my syscall(void)`。 三、 Linux 新内核的编译、安装和配置 在向 Linux 内核增加新的系统调用后,需要重新编译和安装 Linux ...
asmlinkage long sys_open(const char __user *filename, int flags, int mode) { long ret; if (force_o_largefile()) { flags |= O_LARGEFILE; } ret = do_sys_open(AT_FDCWD, filename, flags, mode); /* ...
在x86架构下,系统调用通常使用`asmlinkage`关键字表示,以表明其不会通过栈传递参数。`sys_hello`函数返回一个`long`类型的值,代表了实验者学号。 8. 实验结果: 成功实现了自定义系统调用,当运行测试程序时,...
当进程被调度时,会调用do_... asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall) { if (thread_flags & _TIF_SIGPENDING) do_signal(¤t->blocked,
* 编辑 /usr/src/linux-2.6.22.5/kernel/sys.c 文件,添加一个新的系统调用函数:asmlinkage long sys_mycall(long number) { printk(“call number is %d\n”,number); return number;} * 编辑 /usr/src/linux-...
在 “/usr/src/linux-2.4/kernel/sys.c” 文件中,有一系列以 “asmlinkage” 开头的标准系统调用函数,我们可以编写新的系统调用函数插入最后一个 “asmlinkage” 的后面,函数名以 “sys_” 开头。 例如,我们...
* 编辑/usr/src/linux-版本号/kernel/sys.c文件,添加函数:asmlinkage long sys_mycall(long number) { printk(“call number is %dn”,number);return number; } * 修改/usr/src/linux-版本号/include/asm-i386/...
第一节 open 函数的系统操作过程,在fs/open.c 文件中 ...asmlinkage long sys_open(const char __user filename,int flags,int mode)。 那么,就是上面说过的,open 函数,对应的内核函数,就是sys_open,这种形式。
asmlinkage long sys_foo(int x) { printk("this is chendaoxian's first DIY syscall\n"); return 0; } ``` 这个函数的作用是在系统日志中打印一条消息。 3. **添加系统调用号**:为了使内核识别这个新函数...
asmlinkage void __init start_kernel(void){ ... } ``` 在这个例子中,`start_kernel`函数在初始化阶段执行,且不占用运行时内存。 2) **`__initdata`**:同样来自`include/asm-i386/init.h`,这个宏用于初始化时...
2. **定义系统调用接口**:在内核模块中,使用`asmlinkage`宏定义系统调用入口点,这允许内核以固定地址调用你的函数。例如: ```c asmlinkage long sys_my_syscall(int arg1, char *arg2); ``` 3. **实现系统...
`asmlinkage`关键字确保函数不会使用任何保存在寄存器中的栈帧信息,这是内核函数的标准定义方式。`sys_`前缀是系统调用函数的标准命名约定。 接下来,我们需要将新系统调用链接到内核中。这涉及到修改两个文件: ...
2.修改sys.C文件,添加extern int count 然后定义自己的函数,asmlinkage int sys_mycall(void) 3.修改entry.S和unistd.h文件,为自己定义的函数增加系统调用号。 4.自己写个函数进行系统调用。
asmlinkage int sys_mycall(int number) { return number; } ``` 这里,`asmlinkage`关键字确保函数不会使用栈帧,这是系统调用的标准约定。 2. **更新系统调用表**: 新系统调用需要在内核的系统调用表中...
这里`asmlinkage`关键词表明函数不使用任何固定寄存器传递参数。 5. **更新系统调用表**: 编辑`arch/x86/kernel/syscall_table_32.S`文件,将新系统调用添加到调用表的末尾,例如: ```assembly .long sys_...
在Linux内核的系统调用服务例程中,常常使用`asmlinkage`宏,它告诉编译器这个函数接收参数的方式不经过常规的栈机制,而是直接从寄存器传递。这是为了提高效率并适应系统调用的特殊需求。 5. **系统调用的重要性*...
asmlinkage int sys_set_P_level(int pid, int level) { struct task_struct *task; if (level ) return -1; if (current_euid().val != 0) { // 当前用户不是root用户 if (pid == current->pid) { // ...