内核进程基础

article/2025/7/5 16:20:46

进程定义

操作系统作为硬件的使用层,提供使用硬件资源的能力;进程作为操作系统的使用层,提供使用操作系统抽象出的资源层的能力。

进程:是指计算机中已运行的程序。进程本身不是基本的运行单位,而是线程的容器。程序是指令、数据及其组织形式的描述,进程才是程序(指令和数据)的真正运行实例。

Linux内核把进程叫做task(任务),进程的虚拟地址空间可分为用户虚拟地址空间内核虚拟地址空间,所有进程共享内核虚拟地址空间(内核页表全局唯一),每个进程有独立的用户虚拟地址空间。

进程有两种特殊的形式:没有用户虚拟地址空间的进程叫内核线程;共享用户虚拟地址空间的进程叫用户线程。共享同一个用户虚拟地址空间的所有用户线程叫线程组。


linux arm64架构进程虚拟地址空间布局:

- <font style="color:rgb(64, 64, 64);">用户空间,低地址(地址范围 </font>`**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">0x0000_0000_0000_0000 - 0x0000_FFFF_FFFF_FFFF</font>**`<font style="color:rgb(64, 64, 64);">)。</font>
- <font style="color:rgb(64, 64, 64);">内核空间,高地址(地址范围 </font>`**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">0xFFFF_0000_0000_0000 - 0xFFFF_FFFF_FFFF_FFFF</font>**`<font style="color:rgb(64, 64, 64);">)。</font>

Linux进程四要素

  • 有一段程序供其执行;
  • 有进程专用的系统堆栈空间;
  • 在内核有**task_struct**数据结构(进程描述符);
  • 有独立的存储空间,拥有专有的用户空间;

如果有前三条而缺少第四条,则称为线程;如果完全没有用户空间,则称为内核线程;如果共享用户空间则称为用户线程

进程描述符task_struct

linux中每个进程都应该一个进程描述符task_struct

内核为每个进程分配一个task_struct结构体;实际分配两个连续物理页面(8192字节);

struct task_struct {volatile long			state; // 进程的状态标志void				*stack; // 指向内核栈,每个进程都有一个内核栈/*下面这4个是进程调度策略和优先级*/int				prio;int				static_prio;int				normal_prio;unsigned int			rt_priority;const struct sched_class	*sched_class; // 表示该进程所属的调度器类int				nr_cpus_allowed;const cpumask_t			*cpus_ptr; // 允许进程在哪些CPU上运行cpumask_t			cpus_mask;// 这两个指针指向内存描述符。进程:mm和active_mm指向同一个内存描述符。内核线程:mm是空指针,// 当内核线程运行时,active_mm指向从进程借用内存描述符struct mm_struct		*mm; // 指向内存描述符; mm设置为NULL,则为内核线程struct mm_struct		*active_mm;pid_t				pid; // 全局的进程号pid_t				tgid; // 全局的线程组标识符/* Real parent process: */struct task_struct __rcu	*real_parent; // 指向真实的父进程/* Recipient of SIGCHLD, wait4() reports: */struct task_struct __rcu	*parent; // 指向父进程;如果进程被另一个进程使用系统调用跟踪,那么父进程是跟踪进程;// 否则是real_parentstruct task_struct		*group_leader; // 指向线程组的组长struct hlist_node		pid_links[PIDTYPE_MAX]; // 进程号,进程组标识符和会话标识符/* Objective and real subjective task credentials (COW): */const struct cred __rcu		*real_cred; // 指向主体和真实课题证书/* Effective (overridable) subjective task credentials (COW): */const struct cred __rcu		*cred; // 指向有效客体证书char				comm[TASK_COMM_LEN]; // 进程名称// 下面这两个成员用于UNIX系统:信号量和共享内存
#ifdef CONFIG_SYSVIPCstruct sysv_sem			sysvsem;struct sysv_shm			sysvshm;
#endif...
}

进程创建方法

在Linux内核中,新进程是从一个已经存在的进程中复制出来的;内核使用静态数据结构构造出0号内核线程,0号内核线程分叉生成1号内核线程和2号内核线程(kthreadd线程)。1号内核线程完成初始化后装载用户程序,变成1号进程,其他进程都是1号进程或者它的子孙进程分叉生成的;其他内核线程是kthreadd线程分叉生成的。

linux提供了2个系统调用(forkclone),都可以用来创建新的进程。fork是最常用的方式。fork创建的新进程是原进程的副本,采用了写时复制技术。

fork在内核中将工作委托给_do_fork,其中主要的工作是copy_process

当前进程执行其它程序的方法

在Linux中,**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">fork()</font>****<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">exec()</font>** 是进程创建和程序执行的核心系统调用,通常结合使用以实现新进程的启动(如Shell运行命令)。

fork()复制当前进程(父进程),生成一个几乎完全相同的子进程,使用了写时复制(COW)

在子进程中通过<font style="color:rgb(64, 64, 64);">exec()</font>执行新程序。加载新程序到当前进程空间,替换原有代码、数据、堆栈等。

下面是一个通过<font style="color:rgb(64, 64, 64);">fork</font>+<font style="color:rgb(64, 64, 64);">exec</font>,实现在当前进程中执行<font style="color:rgb(64, 64, 64);">ls</font>命令的测试代码。

#include <stdio.h>      // printf, perror
#include <unistd.h>     // fork, execl
#include <sys/types.h>  // pid_t
#include <sys/wait.h>   // waitint main() {pid_t pid;// 创建子进程pid = fork();if (pid < 0) {// fork 失败perror("fork failed");return 1;}if (pid == 0) {// 子进程printf("Child process (PID: %d) is running `ls -l`...\n", getpid());// 使用 execl 执行 /bin/ls 程序,参数依次是:// 第一个参数:程序路径// 第二个参数:argv[0],约定俗成写程序名(可随意,但最好与实际命令一致)// 后续参数:命令行参数(可多个),以 NULL 结尾execl("/bin/ls", "ls", "-l", NULL);// 如果 exec 成功,上面那句就会替换当前进程,下面的不会执行perror("exec failed");  // exec 调用失败return 1;} else {// 父进程printf("Parent process (PID: %d), waiting for child (PID: %d)...\n", getpid(), pid);// 等待子进程结束int status;waitpid(pid, &status, 0);  // 也可以用 wait(&status)if (WIFEXITED(status)) {printf("Child exited with status %d\n", WEXITSTATUS(status));} else {printf("Child terminated abnormally\n");}}return 0;
}

参考资料

  1. Professional Linux Kernel Architecture,Wolfgang Mauerer
  2. Linux内核深度解析,余华兵
  3. Linux设备驱动开发详解,宋宝华
  4. linux kernel 4.12

http://www.hkcw.cn/article/DQrUGseTUZ.shtml

相关文章

nic_monitor-全面监控以太网、IB、RoCE网络流量的工具

本文提供三个工具,1. nic_monitor 使用脚本语言 Bash Shell 编写的,用来监控以太网或者RDMA接口流量使用的。 2. nic_monitor_v2.0_eth.py 通过TUI界面实时显示以太网流量的工具,使用Python3编写的。3. nic_monitor_v2.1_rdma.py 通过TUI界面实时显示 IB 和 RoCE 流量的工具…

【论文解读】CVPR2023 PoseFormerV2:3D人体姿态估计(附论文地址)

论文链接&#xff1a;https://arxiv.org/pdf/2303.17472 源码链接&#xff1a;https://github.com/QitaoZhao/PoseFormerV2 Abstract 本文提出了 PoseFormerV2&#xff0c;通过探索频率域来提高 3D 人体姿态估计的效率和鲁棒性。PoseFormerV2 利用离散余弦变换&#xff08;DC…

01流程定位

1.以客户为中心&#xff0c;端到端创造价值 大家要思考一个核心问题&#xff0c;企业用什么为客户创造价值&#xff1f; 流程管理大师-迈克而哈默博士回答&#xff0c;不是产品和服务&#xff0c;而是业务流程&#xff0c;是创造、交付产品和服务背后的各种业务流程&#xff0…

【计算机网络】传输层TCP协议——协议段格式、三次握手四次挥手、超时重传、滑动窗口、流量控制、

&#x1f525;个人主页&#x1f525;&#xff1a;孤寂大仙V &#x1f308;收录专栏&#x1f308;&#xff1a;计算机网络 &#x1f339;往期回顾&#x1f339;&#xff1a; 【计算机网络】传输层UDP协议 &#x1f516;流水不争&#xff0c;争的是滔滔不息 一、TCP协议 UDP&…

AI炼丹日志-24 - MCP 自动操作 提高模型上下文能力 Cursor + Sequential Thinking Server Memory

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; Java篇&#xff1a; MyBatis 更新完毕目前开始更新 Spring&#xff0c;一起深入浅出&#xff01; 大数据篇 300&#xff1a; Hadoop&…

yolov8改进模型

YOLOv8 作为当前 YOLO 系列的最新版本&#xff0c;已经具备出色的性能。若要进一步改进&#xff0c;可以从网络架构优化、训练策略增强、多任务扩展和部署效率提升四个方向入手。以下是具体改进思路和实现示例&#xff1a; 1. 网络架构优化 (1) 骨干网络增强 引入 Transform…

单卡4090部署Qwen3-32B-AWQ(4bit量化)-vllm

单卡4090部署Qwen3-32B-AWQ(4bit量化) 模型&#xff1a;Qwen3-32B-AWQ(4bit量化) 显卡&#xff1a;4090 1 张 python版本 python 3.12 推理框架“vllm 重要包的版本 vllm0.9.0创建GPU云主机 这里我使用的是优云智算平台的GPU&#xff0c;使用链接可以看下面的 https://blog.…

【C++并发编程01】初识C++并发编程

1、并发是什么 并发是指两个或更多独立的活动同时发生&#xff0c;现实生活中常见的并发场景如边吃饭边看手机。 1.1、计算机中的并发&#xff1a; 计算机领域的并发是指在单个系统里同时执行多个独立的任务&#xff0c;而非顺序的进行一些活动。 我们在电脑上能够边听音乐边和…

【NLP入门系列一】NLP概述和独热编码

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 博主简介&#xff1a;努力学习的22级本科生一枚 &#x1f31f;​&#xff1b;探索AI算法&#xff0c;C&#xff0c;go语言的世界&#xff1b;在迷茫中寻找光芒…

【知识点】第2章:Python程序实例解析

文章目录 知识点整理Python程序语法元素分析 练习题判断题填空题选择题 知识点整理 Python程序语法元素分析 Python程序包括格式框架、注释、变量、表达式、分支语句、循环语句、函数等语法元素。 程序的格式框架 Python语言采用严格的 “缩进” 来表明程序的格式框架。缩进…

Webug4.0靶场通关笔记05- 第5关SQL注入之过滤关键字

目录 一、代码审计 1、源码分析 2、SQL注入分析 &#xff08;1&#xff09;大小写绕过 &#xff08;2&#xff09;双写绕过 二、第05关 过滤型注入 1、进入靶场 2、sqlmap渗透 &#xff08;1&#xff09;bp抓包保存报文 &#xff08;2&#xff09;sqlmap渗透 &…

001在线拍卖系统技术揭秘:构建高效交互的竞拍平台

在线拍卖系统技术揭秘&#xff1a;构建高效交互的竞拍平台 在互联网经济蓬勃发展的当下&#xff0c;在线拍卖系统以其独特的交易模式&#xff0c;吸引着众多用户参与。该系统涵盖个人中心、用户管理等多个关键模块&#xff0c;通过前台展示与后台录入的协同运作&#xff0c;满…

LabVIEW输血袋字符智能检测系统

针对医疗行业输血袋字符检测需求&#xff0c;基于 LabVIEW 图形化开发平台与基恩士&#xff08;KEYENCE&#xff09;机器视觉硬件&#xff0c;构建高精度、高可靠性的字符在线识别系统。通过选用基恩士工业相机、光源及 NI 数据采集设备等硬件&#xff0c;结合 LabVIEW 强大的图…

Conditional注解的使用

目录 1.ConditionalOnBean 1.1、作用 1.2、使用场景 2. ConditionalOnMissingBean 2.1、作用 2.2、使用场景 3. 两者结合使用 4. 高级用法&#xff1a; 5. 注意事项 6. 实际应用场景 前言 在 Spring 框架中&#xff0c;ConditionalOnBean 和 ConditionalOnMissingBea…

CTFshow web3

文件包含和伪协议 用GET传入一个URL值&#xff0c;/?url文件路径 伪协议php://input 用来执行PHP代码&#xff0c;将POST请求当作PHP代码执行 测试一下&#xff0c;可以正确解析 拿到FLAG 还有一种解法&#xff0c;写入一句话木马 #Payload #把一句话木马写入2.phpdata:/…

数据库暴露--Get型注入攻击

1.背景知识 1.1Post、Get的对比 特性GET 方法POST 方法HTTP 方法类型GETPOST数据位置URL 查询字符串(?key=value)请求体(Request Body)数据可见性明文显示在 URL 和浏览器历史中不可见(除非开发者工具查看)数据长度限制受 URL 长度限制(通常约 2048 字符)无明确限制(…

Linux 1.0.4

父子shell linux研究的就是shell 打开两个窗口就是两个shell 终端的软件有很多 bash也是一个软件 我们在terminal里面再打开一个bash&#xff0c;然后再次使用ps命令发现多出来一个bash&#xff0c;之后点击exit只是显示了一个exit&#xff0c;这个只是退出了在terminal中打开…

挖洞日记 | 记一次MSSQL注入绕waf过程

在挖漏洞时&#xff0c;使用 xia sql 插件发现一个注入点&#xff0c;经过测试发现存在 waf 拦截记录一下。 在查询中发现单引号是空白页面&#xff0c;在加一个单引号&#xff0c;显示空数据&#xff0c;但是有回显&#xff0c;初步判断 pname 存在 SQL注入。 然后判断列数1o…

Linux-pcie ranges介绍

参考链接&#xff1a;https://elinux.org/Device_Tree_Usage#PCI_Host_Bridge pcie bar高低端BAR起始地址介绍 pcie设备树节点 / {compatible "rockchip,rk3588";interrupt-parent <&gic>;#address-cells <2>;#size-cells <2>;pcie3x4: p…

模块化设计,static和extern(面试题常见)

文章目录 一、函数的声明和定义1.1 单个文件1.2 多个文件1.3 static和extern1.3.1 static修饰局部变量1.3.2 static修饰全局变量1.3.3 static修饰函数 总结 一、函数的声明和定义 1.1 单个文件 一般我们在使用函数的时候&#xff0c;直接将函数写出来就使用了 题目:写一个函数…