进程调度之thread_info和thread_struct

ThreadInfo结构和内核栈的两种关系 本来本节是要学习内核启动的第一个进程的建立,也就是0号进程,也称idle进程,也称swapper进程。但是在学习第一个进程建立之前需要先学习threadinfo和内核栈的关系。 目前内核存在两种threadinfo和内核的关系,接下来我们通过画图一一举例说明。 ThreadInfo结构在内核栈中 Threadinfo结构存储在内核栈中,这种方式是最经典的。因为task_struct结构... 阅读详情

对于thread_struct


  • 内核还需要存储每个进程的PCB信息, linux内核是支持不同体系的的, 但是不同的体系结构可能进程需要存储的信息不尽相同, 这就需要我们实现一种通用的方式, 我们将体系结构相关的部分和无关的部门进行分离

对于PPC来说,结构体如下

struct thread_struct {
	unsigned long	ksp;		/* Kernel stack pointer */
#ifdef CONFIG_PPC64
	unsigned long	ksp_vsid;
#endif
	struct pt_regs	*regs;		/* Pointer to saved register state */
	mm_segment_t	fs;		/* for get_fs() validation */
#ifdef CONFIG_PPC32
	void		*pgdir;		/* root of page-table tree */
#endif
#if defined(CONFIG_4xx) || defined (CONFIG_BOOKE)
	unsigned long	dbcr0;		/* debug control register values */
	unsigned long	dbcr1;
#endif
	double		fpr[32];	/* Complete floating point set */
	struct {			/* fpr ... fpscr must be contiguous */

		unsigned int pad;
		unsigned int val;	/* Floating point status */
	} fpscr;
	int		fpexc_mode;	/* floating-point exception mode */
	unsigned int	align_ctl;	/* alignment handling control */
#ifdef CONFIG_PPC64
	unsigned long	start_tb;	/* Start purr when proc switched in */
	unsigned long	accum_tb;	/* Total accumilated purr for process */
#endif
	unsigned long	dabr;		/* Data address breakpoint register */
#ifdef CONFIG_ALTIVEC
	/* Complete AltiVec register set */
	vector128	vr[32] __attribute((aligned(16)));
	/* AltiVec status */
	vector128	vscr __attribute((aligned(16)));
	unsigned long	vrsave;
	int		used_vr;	/* set if process has used altivec */
#endif /* CONFIG_ALTIVEC */
#ifdef CONFIG_SPE
	unsigned long	evr[32];	/* upper 32-bits of SPE regs */
	u64		acc;		/* Accumulator */
	unsigned long	spefscr;	/* SPE & eFP status */
	int		used_spe;	/* set if process has used spe */
#endif /* CONFIG_SPE */
};

而核心是如下数据结构是PPC的寄存器信息。

struct pt_regs {
	unsigned long gpr[32];
	unsigned long nip;
	unsigned long msr;
	unsigned long orig_gpr3;	/* Used for restarting system calls */
	unsigned long ctr;
	unsigned long link;
	unsigned long xer;
	unsigned long ccr;
#ifdef __powerpc64__
	unsigned long softe;		/* Soft enabled/disabled */
#else
	unsigned long mq;		/* 601 only (not used at present) */
					/* Used on APUS to hold IPL value. */
#endif
	unsigned long trap;		/* Reason for being here */
	/* N.B. for critical exceptions on 4xx, the dar and dsisr
	   fields are overloaded to hold srr0 and srr1. */
	unsigned long dar;		/* Fault registers */
	unsigned long dsisr;		/* on 4xx/Book-E used for ESR */
	unsigned long result;		/* Result of a system call */
};

对于X86来说,定义则依赖于X86的CPU实现

struct thread_struct {
/* cached TLS descriptors. */
	struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
	unsigned long	esp0;
	unsigned long	sysenter_cs;
	unsigned long	eip;
	unsigned long	esp;
	unsigned long	fs;
	unsigned long	gs;
/* Hardware debugging registers */
	unsigned long	debugreg[8];  /* %%db0-7 debug registers */
/* fault info */
	unsigned long	cr2, trap_no, error_code;
/* floating point info */
	union i387_union	i387;
/* virtual 86 mode info */
	struct vm86_struct __user * vm86_info;
	unsigned long		screen_bitmap;
	unsigned long		v86flags, v86mask, saved_esp0;
	unsigned int		saved_fs, saved_gs;
/* IO permissions */
	unsigned long	*io_bitmap_ptr;
 	unsigned long	iopl;
/* max allowed port in the bitmap, in bytes: */
	unsigned long	io_bitmap_max;
};

该结构体处于进程数据结构里面:

struct task_struct

    thread_struct thread;

 

 

对于thread_info


  • 内核栈跟thread_info共用结构体

用一种通用的方式来描述进程, 这就是struct task_struct, 而thread_info就保存了特定体系结构的汇编代码段需要访问的那部分进程的数据,我们在thread_info中嵌入指向task_struct的指针, 则我们可以很方便的通过thread_info来查找task_struct

struct thread_info {
	struct task_struct	*task;		/* main task structure */
	struct exec_domain	*exec_domain;	/* execution domain */
	unsigned long		flags;		/* low level flags */
	unsigned long		status;		/* thread-synchronous flags */
	__u32			cpu;		/* current CPU */
	int			preempt_count;	/* 0 => preemptable, <0 => BUG */


	mm_segment_t		addr_limit;	/* thread address space:
					 	   0-0xBFFFFFFF for user-thead
						   0-0xFFFFFFFF for kernel-thread
						*/
	void			*sysenter_return;
	struct restart_block    restart_block;

	unsigned long           previous_esp;   /* ESP of the previous stack in case
						   of nested (IRQ) stacks
						*/
	__u8			supervisor_stack[0];
};
union thread_union {
	struct thread_info thread_info;
	unsigned long stack[THREAD_SIZE/sizeof(long)];
};

该结构体在task_struct的位置如下:

看一下这个函数就明白了

static struct task_struct *dup_task_struct(struct task_struct *orig)
{
	struct task_struct *tsk;
	struct thread_info *ti;//声明

	prepare_to_copy(orig);

	tsk = alloc_task_struct();
	if (!tsk)
		return NULL;

	ti = alloc_thread_info(tsk);//分配空间
	if (!ti) {
		free_task_struct(tsk);
		return NULL;
	}

	*tsk = *orig;
	tsk->stack = ti;//与task_struct关联
	setup_thread_stack(tsk, orig);

#ifdef CONFIG_CC_STACKPROTECTOR
	tsk->stack_canary = get_random_int();
#endif

	/* One for us, one for whoever does the "release_task()" (usually parent) */
	atomic_set(&tsk->usage,2);
	atomic_set(&tsk->fs_excl, 0);
#ifdef CONFIG_BLK_DEV_IO_TRACE
	tsk->btrace_seq = 0;
#endif
	tsk->splice_pipe = NULL;
	return tsk;
}

 

 

 

 

Linux进程内核栈与thread_info结构详解--Linux进程的管理与调度(九)

http://blog.youkuaiyun.com/gatieme/article/details/51577479

Linux下0号进程的前世(init_task进程)今生(idle进程)----Linux进程的管理与调度(五)
https://blog.youkuaiyun.com/gatieme/article/details/51484562

Linux内核分析(八):Linux进程调度的时机和进程切换
https://blog.youkuaiyun.com/u013291303/article/details/70199645

Linux内核分析(六):进程的描述和进程的创建
https://blog.youkuaiyun.com/u013291303/article/details/68954599
 

进程内核栈、用户栈
https://blog.youkuaiyun.com/bailyzheng/article/details/8015618

 

操作系统整理(二)--进程管理 本文接着上一章,继续介绍linux中的子系统,本篇介绍进程子系统 阅读详情

相关推荐

【linux软件基础知识】与调度相关的进程描述符

如果进程的优先权等于k(其取值范围是0到139),run_list字段把该进程链入优先级为k的可运行进程的链表中。80x86 体系结构包括了一个特殊的段类型,叫任务状态段 (Task State Segment,TSS来存放硬件上下文。尽管Linux 并不使用硬件上下文(参见下文)切换,但是强制它为系统中每个不同的 CPU 创建一个TSS。在每次进程切换时,被替换进程的硬件上下文必须保存在别处。

262

1231

#include #include #include #include struct menber {     int a;     char *s; }; void *create(void *arg) {     struct menber *temp;     temp=(struct menber *)arg;     printf("me

YGGkk的博客 418

[苹果开发者账号]03 申请APPID、苹果开发者账号 常见问题整理

目录:问题持续更新问题一:提示:抱歉,您暂时不能注册问题二:Apple Developer Support提示:联系我们以继续流程 问题一:提示:抱歉,您暂时不能注册 申请苹果开发者账号,应该先注册AppleID,由于很多都是申请的公司使用的苹果开发者账号。一般操作申请动作的人,可能是新手操作,也可能图方便,有些信息会随便填写。 有些人会把姓名填写为,公司的产品、简称、缩写等等。这是不对的。 还有出生日期也会随便乱填。生日如果填写的不对,会被苹果限制使用一些功能的(苹果给的提示不是太明确)。 当生日填写的

专注于技术开发、项目管理 1万+

linux内核中task_struct与thread_info及stack三者的关系

在linux内核中进程以及线程(多线程也是通过一组轻量级进程实现的)都是通过task_struct结构体来描述的,我们称它为进程描述符。而thread_info则是一个与进程描述符相关的小数据结构,它同进程的内核态栈stack存放在一个单独为进程分配的内存区域。由于这个内存区域同时保存了thread_info和stack,所以使用了联合体来定义,相关数据结构如下(基于4.4.87版本内核): thread_union联合体定义: union thread_union { struct threa

u014426028的博客 4790

Linux系统下奥比中光Astra Pro相机SDK部署与避坑指南

本文详细指导了在Linux系统下部署奥比中光Astra Pro深度相机SDK的全过程,涵盖系统准备、SDK安装、设备权限配置及常见问题排查。重点解析了USB设备规则配置这一关键步骤,并提供了Python与C++项目的集成方法,旨在帮助开发者快速完成相机配置,避免常见陷阱。

weixin_28455801的博客 300

Xilnx大学计划/XUP ZYNQ ZU开发板

TUL PYNQ™-ZU板,基于Xilinx Zynq UltraScale+ MPSoC,是为Xilinx大学项目设计的,以支持Xilinx PYNQ (Python Productivi-ty for Zynq)开源框架和嵌入式系统开发。

weixin_57025922的博客 947

深入理解Linux内核笔记——第三章进程

深入理解Linux内核笔记——第三章进程 进程 一、进程、轻量级进程和线程 (1)进程描述符 进程状态state 可运行状态TASK_RUNNING 可中断的等待状态TASK_INTERRUPTIBLE 不可中断的等待状态TASK_UNINTERRUPTIBLE 暂停状态TASK_STOPPED 跟踪状态TASK_TUACED 僵死状态EXIT_ZOMBIE 僵死撤消状态EXIT_DEAD set_task_state和set_current_state (2)标识一个进程 进程和进程描述符有严格的一一对应

qq_43527944的博客 410

IWR6843ISK+DCA1000EVM 本人遇到的所有报错和解决方案

本文详解了初次使用DCA1000EVM和mmave studio遇到的一系列的问题以及解决方法

2301_77883976的博客 3306

Linux Kernel:thread_info与task_struct

其他Exception level下,可以使用SP_EL0或者当前Exception level所对应的SP_ELn寄存器;具体使用SP_EL0还是SP_EL1是由PSTATE.SP决定,对应的寄存器是Spsel。若Spsel==0,那么强制使用SP_EL0,否则使用用SP_ELn。,每当切换开始时首先需要做的是保存当前进程上下文到内核栈中,准备next进程环境之后切到next进程堆栈。内核栈中的最低地址中,相较之前的版本避免了栈溢出的问题。用来描述进程的通用数据,而针对不同架构的数据则存储在。

qq_34968572的博客 1410

STM32+4G模块+MQTT协议:从零构建稳定可靠的物联网通讯链路

本文详细介绍了如何利用STM32、4G模块和MQTT协议构建稳定可靠的物联网通讯链路。通过硬件选型、AT指令配置和MQTT连接实战,帮助开发者实现低功耗、高可靠性的数据传输,特别适合户外和移动场景应用。

weixin_29191081的博客 334

模拟量传输4-20ma电流

大家可能会非常熟悉RS232,RS485,CAN等工业上常用的总线,他们都是传输数字信号的方式。那么,我们用什么方式来传输模拟信号呢?工业上普遍需要测量各类非电物理量,例如温度、压力、速度、角度等,这些都需要转换成模拟量电信号才能传输到几百米外的控制室或显示设备上。工业上最广泛采用的是用4~20mA电流来传输模拟量。 采用电流信号的原因是不容易受干扰,因为工业现场的噪声电压的幅度可能达到数V,但是噪声的功率很弱,所以噪声电流通常小于nA级别,因此给4-20mA传输带来的误差非常小;电流源内阻趋于无穷.

tangdongming的博客 1万+

【随笔】thread_info

看ULK3rd讲进程抢占提到thread_info.flags(调度基础、主动调度和被动调度),所以追了一下。 32bit机器上是这样定义的(https://elixir.bootlin.com/linux/v2.6.39.4/source/arch/x86/include/asm/thread_info.h#L26): struct thread_info { struct task_struct *task; /* main task structure */ __u32 flags

厚积薄发者,轻舟万重山 976

modbus-esp8266库深度解析:工业级Modbus协议栈实现

Modbus是一种广泛应用于工业自动化领域的通用串行通信协议,其核心在于标准化的功能码、寄存器模型与帧结构设计。基于RTU、ASCII和TCP三种传输变体,Modbus协议通过主从架构实现设备间可靠数据交互,具备低开销、高兼容性与强实时性等技术价值。在边缘计算与工业物联网场景中,它被广泛用于PLC通信、传感器数据采集、HMI集成及远程固件升级(FOTA)等关键任务。针对ESP8266/ESP32等Wi-Fi微控制器平台,modbus-esp8266库提供了完整协议栈支持,涵盖多实例并发、回调驱动架构、零拷贝

weixin_42315569的博客 350

x86 linux的进程调度,x86体系结构下Linux-2.6.26的进程调度和切换

进程调度相关数据结构task_structtask_struct是进程在内核中对应的数据结构,它标识了进程的状态等各项信息。其中有一项thread_struct结构的变量thread,记录了CPU相关的进程状态信息,如内核控制的断点和栈指针等。在内核中获得当前进程task_struct结构使用宏current,该宏读取变量current_task得到指针。thread_union和thread_i...

weixin_33810040的博客 234

vue3 - 高德地图定位出错Get ipLocation failed.Geolocation permission denied.(info: “FAILED“ | status: 0)报错解决!

vue3,nuxt3,高德地图,定位,位置,报错,AMap.Geolocation,解决报当前定位失败,高德地图H5 定位失败报错,web网页网站,报错详细解决教程,Get ipLocation failed.Geolocation permission denied.,高德地图定位报错info: "FAILED",高德地图status: 0,已经是https了还是报错,确保了浏览器位置已经开了,手机定位也开了,没解决,H5页面在ios的浏览器上使用 高德地图 报当前定位失败Geolocation,移动端设

✅ 精选推荐文章 6771

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

linux 进程及调度基础知识

介绍了进程,线程,调度的相关基础知识

vertor11的博客 1027

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Linux5.10 源码解析 - 进程描述符

进程描述符的一些细节分析,主要元素的作用。

系统!内核! 940

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

task_struct

1、进程的基本信息 1.1 标识一个进程——PID 每个进程都必须拥有它自己的进程描述符; 因此,即使共享内核大部分数据结构的轻量级进程(后面会提到), 也有它们自己的task_struct结构。 进程和进程描述符之间有非常严格的一一对应关系,所以我们可以方便地使用32位进程描述符地址标识进程。 进程描述符指针(task_struct*)指向这些地址。内核对进程的大部份引用都是通过进程描述符指针...

sunshineywz的博客 1627

第三章 进程管理

​ 读书笔记

weixin_44575657的博客 129

【Linux】进程描述符

linux进程管理(1)---进程描述符 进程描述符 Linux使用进程描述符数据结构记录现场信息,然后给予进程描述符管理进程,包括进程的创建、调度、消亡等操作。 进程除了包括运行着的程序,还包括系统资源(当前CPU现场、调度信息、进程间关系等)。记录这些线程信息的数据结构就是进程描述符 task_struct(include/linux/sched.h中) 每个进程都有一个进程描述符,记录...

Twinkle 1672

Android内核结构体

typedef unsigned long mm_segment_t;struct thread_info { unsigned long flags; /* low level flags */ int preempt_count; /* 0 => preemptable, <0 => bug */ mm_segment_t

trojancyborg的专栏 613

Linux内核之进程管理

关键知识点 进程相关结构体task_struct和thread_info 与进程有关的系统调用 内核调度进程总体思想 进程调度算法CFS ————————–未完待续————————0x00 与进程相关的数据结构 task_struct http://lxr.linux.no/linux+v4.9/include/linux/sched.h thread_info http://lxr.li

lxb122435677的博客 318

linux 当前进程(current)

  static inline struct task_struct * get_current(void) { return current_thread_info()-&gt;task; } #define current get_current()   /* how to get the thread information struct from C */ sta...

jxluoix的专栏 511

内核进程切换实现分析

当我们在linux编写用户态程序时并不需要考虑进程间是如何切换的, 即使当我们编写驱动程序时也只需调用一些阻塞接口来让渡cpu. 但是cpu究竟是如何切换进程的, 在进程切换过程中需要做什么, 今天我们通过分析内核schedule()的实现来看下内核是如何完成进程切换的. 先看下几个相关的数据结构: 1 struct thread_info { 2 unsigned lo...

weixin_34270606的博客 110

内核修炼之进程

进程管理 进程 线程 task_struct thread_info 进程状态 进程组织方式 进程的生命周期 进程初始化 fork、vfork、内核线程 execexit 进程调度 抢占、非抢占 实时、非实时 switch_mm、switch_to、schedule 策略:优先级、类型、时间片 nice值、权重 调度类 调度策略 负载均衡 ...

win9 651
上一篇: USB学习之一 代码分析和学习心得之初始化流程以及读写流程
下一篇: linux内核定位方法总结1 ECC hung-task和原子操作 反汇编调用栈
天麓
博客等级 码龄22年 323粉丝 437原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值