linux内核中的asmlinkage宏

阅读数:268 评论数:0

跳转到新版页面

分类

Linux

正文

一、概述

在 Linux 内核编程中,asmlinkage 是一个关键字,用于告诉编译器该函数将通过堆栈而不是寄存器接收所有的参数。这个宏主要用于那些需要从用户空间通过系统调用接口调用的函数。在系统调用的上下文中,参数是通过堆栈传递的,以确保所有的系统调用都有一个统一的接口。

asmlinkage 主要用在系统调用的包装函数中,例如:

asmlinkage long sys_gettimeofday(struct timeval __user *tv, struct timezone __user *tz);

这个函数是 gettimeofday 系统调用的内核实现。由于这个函数需要从用户空间被调用,所以它使用 asmlinkage 来确保参数通过堆栈传递。

在现代的 Linux 内核中,由于系统调用的实现方式有了变化(比如使用了更高效的系统调用表),asmlinkage 的使用已经不像以前那么频繁了。但是,对于理解 Linux 内核的历史和一些旧代码,了解 asmlinkage 是很有帮助的。

二、源码相关

这个宏的作用是保持参数在stack中。查看arch/x86/include/asm/linkage.h里面的定义

#ifdef CONFIG_X86_32
#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
#endif

__attribute__((regparm(0))):告诉gcc编译器该函数不需要通过任何寄存器来传递参数,参数只是通过堆栈来传递。
__attribute__((regparm(3))):告诉gcc编译器这个函数可以通过寄存器传递多达3个的参数,这3个寄存器依次为EAX、EDX 和 ECX。更多的参数才通过堆栈传递。这样可以减少一些入栈出栈操作,因此调用比较快。

CPP_ASMLINKAGE 是一个空的宏,用于兼容性目的。

asmlinkage大都用在系统调用中。 有一些情况下是需要明确的告诉编译器,我们是使用stack来传递参数的,比如X86中的系统调用,是先将参数压入stack以后调用sys_*函数的,所以所有的sys_*函数都有asmlinkage来告诉编译器不要使用寄存器来编译




相关推荐

mainline 、longterm、stable、linux-next、snapshot这些名词,都是linux kernel sou

__CONCAT,连接两个参数,##用于粘贴两个参数,#用于替换参数 #define __CONCAT(a, b) a ##

<img src="http://123.56.17.129:2177/images/linux_kernel.png" alt="" /

在编程中,一个符号symbol是一个程序的创建块,它是一个变量名或一个函数名。 内核符号表(Kernel Symbol Table) 内核并不使用符号名。它是通过

在Kernel_path/Makefile中可以查看到 # SPDX-License-Identifier: GPL

一、概述 在 Linux 内核中,printk 是一个类似于用户空间 C 语言中的 printf 函数的内核级日志记录功能。它用于内核代码中输出调试信息到控制台或系统日志。printk 可以在几乎任何

一、概述  在日常工作中,经常会需要对内核进行Debug、或者进行优化工作。一些简单的问题,可以通过dmesg/printk查看,优化借助一些工具进行。 但是当问题逻辑复杂,优化面宽泛的时候,往往无从

上图是Intel手册中对标志寄存器的图示,几个

一、概述 自从Linux内核代码迁移到Git以来,Linux内核配置/构建系统(也称为Kconfig / kbuild)已存在很长时间了。 二、Kconfig (Kernel config) menu

目前x86平台使用的BootLoader基本上都已经是UEFI。 LinuxBoot是&ldquo;反UEFI先锋&rdquo;Google公司提出的固件。 Goog