Linux——不同体系结构下获取current

本文深入解析了Linux内核中获取current(当前进程)的过程。详细介绍了从宏定义到内联汇编的实现路径,展示了如何在X86体系下通过perCPU变量定位当前任务结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

current的含义:

        内核代码可以引用当前进程, 通过存取全局项 current, 它在 <asm/current.h> 中定义, 它产生一个指针指向结构 task_struct, 在 <linux/sched.h> 定义. current 指针指向当前在运行的进程. 在一个系统调用执行期间, 例如 open 或者 read, 当前进程是发出调用的进程. 内核代码可以通过使用 current 来使用进程特定的信息, 如果它需要这样. 实际上, current 不真正地是一个全局变量. 支持 SMP 系统的需要强迫内核开发者去开发一种机制, 在相关的 CPU 上来找到当前进程. 这种机制也必须快速, 因为对 current 的引用非常频繁地发生. 结果就是一个依赖体系的机制, 常常, 隐藏了一个指向 task_struct 的指针在内核堆栈内. 实现的细节对别的内核子系统保持隐藏, 一个设备驱动可以只包含 <linux/sched.h> 并且引用当前进程.

在X86体系中如何获取current的:

        在asm/current.h中我们看到代码如下方式实现:

 10 DECLARE_PER_CPU(struct task_struct *, current_task);
 11 
 12 static __always_inline struct task_struct *get_current(void)
 13 {
 14     return percpu_read_stable(current_task);
 15 }
 16 
 17 #define current get_current()
        在上述代码中我们能过看到其实current其实是一个宏,真实的调用为get_current(),而在get_current()中又调用percpu_read_stable(current_task),下面看一下percpu_read_stable(current_task)的实现:(注:在上述代码中第10行的DECLARE_PER_CPU宏用于在编译时候声明一个perCPU变量该变量被放在一个特殊的段中,原型为DECLARE_PER_CPU(type,name),主要作用是为处理器创建一个type类型,名为name的变量)

        在asm/percpu.h中我们找到了percpu_read_stable(current_task)的实现:

361 #define percpu_read_stable(var)     percpu_from_op("mov", var, "p" (&(var)))

         在这里很清晰,我们继续跟中percpu_from_op("mov", var, "p" (&(var)))

         在asm/percpu.h中我们找了percpu_from_op("mov", var, "p" (&(var)))的实现如下:

180 #define percpu_from_op(op, var, constraint)     \
181 ({                          \
182     typeof(var) pfo_ret__;              \
183     switch (sizeof(var)) {              \
184     case 1:                     \
185         asm(op "b "__percpu_arg(1)",%0"     \
186             : "=q" (pfo_ret__)          \
187             : constraint);          \
188         break;                  \
189     case 2:                     \
190         asm(op "w "__percpu_arg(1)",%0"     \
191             : "=r" (pfo_ret__)          \
192             : constraint);          \
193         break;                  \
194     case 4:                     \
195         asm(op "l "__percpu_arg(1)",%0"     \
196             : "=r" (pfo_ret__)          \
197             : constraint);          \
198         break;                  \
199     case 8:                     \
200         asm(op "q "__percpu_arg(1)",%0"     \
201             : "=r" (pfo_ret__)          \
202             : constraint);          \
203         break;                  \
204     default: __bad_percpu_size();           \
205     }                       \
206     pfo_ret__;                  \
207 })
        percpu_from_op宏中根据不同的sizeof(var)选择不同的分支,执行不同的流程,因为这里是x86体系,所以sizeof(current_task)的值为4,在每个分支中使用了一条的內联汇编代码,其中__percpu_arg(1)为%%fs:%P1(X86)或者%%gs:%P1(X86_64),将上述代码整理后current获取代码如下:

asm(movl "%%fs:%P1","%0" : "=r" (pfo_ret__) :"p" (&(var)) 

        即:将fs段中P1偏移处的值传送给pfo_ret__变量,那么fs段中P1偏移处存放的是什么呢?

        注:本文没有写完,前面这块写了好多天了,接下来的内容还没有分析,求简单的指导:在我的记忆中应该是内核栈的分配的问题,以及thread_info在内核栈中的位置的问题,然后就能够找到task_struct了,求指导相关模块的内核源码位置

总结:

以前是通过如下汇编指令实现的:movl $-8192,%eax; andl %esp, %eax来实现的,执行完这两条指令后,eax中存放的就是thread_info的地址。而现在的代码中再也找不到这样的指令了,以前SMP共享数据很多依靠自旋锁来达到目的,自旋锁是一种忙等锁,在一定程度上造成了进行自旋的CPU上CPU利用率的下降,随着内核的不断发展,更多的使用每个CPU数据(per_cpu_data)的概念,在每一个处理器中各自维护一个以前在多个CPU之间进行共享的数据,如当前运行的任务结构体,以前就是在多个CPU之间共享的。

### VMware Linux 镜像下载与安装教程 #### 一、VMware简介及其功能支持 VMware 是一种广泛使用的虚拟化软件,能够帮助用户在同一台计算机上运行多个操作系统实例。通过 VMware Workstation 或 VMware Player,用户可以在 Windows 和 Linux 主机上创建并管理虚拟机环境。 #### 二、Linux镜像文件获取途径 对于希望在 VMware 中部署 Linux 的用户来说,可以从官方渠道或其他可信资源网站下载所需的 ISO 文件。以下是几个常见的 Linux 发行版以及其对应的官方网站链接: - **Ubuntu**: Ubuntu 提供了一个直观易用的操作系统体验,适合初学者和开发者使用。可以通过访问官网 (https://ubuntu.com/download/desktop)[^1] 获取最新版本的桌面端或服务器端镜像。 - **CentOS/AlmaLinux/Rocky Linux**: CentOS 曾经是一个基于 Red Hat Enterprise Linux 构建的企业级免费发行版;随着 CentOS 停止更新维护,社区推荐转向 AlmaLinux 或 Rocky Linux。这些替代品同样兼容 RHEL 生态体系结构,并且提供长期稳定的支持周期。(http://rockylinux.org/, https://almalinux.org/) [^2] - **Debian GNU/Linux**: Debian 是另一个历史悠久且备受推崇的开源项目之一,它强调自由软件原则和技术稳定性。要获得最新的稳定发布版本,请前往 http://cdimage.debian.org/debian-cd/current/amd64/iso-dvd/[^3]. #### 三、具体操作流程概述 一旦准备好了合适的 .iso 映射文档之后,则按照如下步骤执行实际部署工作: 1. 打开已安装完毕的应用程序——即 VMware Workstation / Fusion Professional Edition; 2. 创建新的虚拟客户机向导:依次选取菜单栏中的【File】-> 【New Virtual Machine...】, 接着遵照屏幕提示逐步填写各项参数设定项直至结束整个初始化过程为止。(注意此时需指定先前所提到过的特定类型 guest OS 及关联路径指向本地存储设备内的目标压缩包位置) 3. 自定义硬件资源配置阶段允许调整 CPU 数量分配比例、内存大小预留额度以及其他外围组件选项比如网络适配器模式选择桥接还是 NAT 等等细节部分均依据个人需求灵活定制即可满足日常应用场景下的性能表现预期效果[^4]; 4. 启动新建好的 VM 实例之前记得核查一遍所有前期准备工作是否均已妥善安排就绪无误后再正式开机加载源码启动引导序列进入图形界面完成后续剩余环节诸如分区布局规划方案确认提交动作等等最终达成既定目的实现成功搭建起一套完整的类 Unix 平台模拟测试环境的目的. ```bash sudo apt update && sudo apt upgrade -y # 更新Ubuntu系统的软件包列表并升级现有安装包至最新状态 yum groupinstall "Development Tools" # 在RHEL系家族成员身上批量预装开发工具链集合体以便开展编程活动等相关任务处理作业. ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值