基于aarch64分析kernel源码 五:idle进程(0号进程)
一、参考
linux — 0号进程,1号进程,2号进程 - 流水灯 - 博客园 (cnblogs.com)
Linux0号进程,1号进程,2号进程_0号进程和1号进程-CSDN博客
二、idle进程的创建流程
start_kernel --> arch_call_rest_init --> rest_init--> cpu_startup_entry --> while(1) { do_idle(); }
start_kernel
函数在完成系统初始化后会进入死循环调用 do_idle
函数,相当于 start_kernel
函数完成初始化后会退化成 idle
进程。
三、idle 进程控制块
idle
进程控制块是 init_task
,init_task
是一个全局静态变量,定义在 init/init_task.c
文件中。
/** Set up the first task table, touch at your own risk!. Base=0,* limit=0x1fffff (=2MB)*/
struct task_struct init_task
#ifdef CONFIG_ARCH_TASK_STRUCT_ON_STACK__init_task_data
#endif__aligned(L1_CACHE_BYTES)
= {
#ifdef CONFIG_THREAD_INFO_IN_TASK.thread_info = INIT_THREAD_INFO(init_task),.stack_refcount = REFCOUNT_INIT(1),
#endif.__state = 0,.stack = init_stack, // init_stack 值定义在链接脚本中(init_stack是内核栈的静态的定义).usage = REFCOUNT_INIT(2),.flags = PF_KTHREAD,.prio = MAX_PRIO - 20,.static_prio = MAX_PRIO - 20,.normal_prio = MAX_PRIO - 20,.policy = SCHED_NORMAL,.cpus_ptr = &init_task.cpus_mask,.user_cpus_ptr = NULL,.cpus_mask = CPU_MASK_ALL,.nr_cpus_allowed= NR_CPUS,.mm = NULL,.active_mm = &init_mm,.restart_block = {.fn = do_no_restart_syscall,},.se = {.group_node = LIST_HEAD_INIT(init_task.se.group_node),},.rt = {.run_list = LIST_HEAD_INIT(init_task.rt.run_list),.time_slice = RR_TIMESLICE,},.tasks = LIST_HEAD_INIT(init_task.tasks),
#ifdef CONFIG_SMP.pushable_tasks = PLIST_NODE_INIT(init_task.pushable_tasks, MAX_PRIO),
#endif
#ifdef CONFIG_CGROUP_SCHED.sched_task_group = &root_task_group,
#endif.ptraced = LIST_HEAD_INIT(init_task.ptraced),.ptrace_entry = LIST_HEAD_INIT(init_task.ptrace_entry),.real_parent = &init_task,.parent = &init_task,.children = LIST_HEAD_INIT(init_task.children),.sibling = LIST_HEAD_INIT(init_task.sibling),.group_leader = &init_task,RCU_POINTER_INITIALIZER(real_cred, &init_cred),RCU_POINTER_INITIALIZER(cred, &init_cred),.comm = INIT_TASK_COMM, // #define INIT_TASK_COMM "swapper" - 0号进程的名称.thread = INIT_THREAD,.fs = &init_fs,.files = &init_files,
#ifdef CONFIG_IO_URING.io_uring = NULL,
#endif.signal = &init_signals,.sighand = &init_sighand,.nsproxy = &init_nsproxy,.pending = {.list = LIST_HEAD_INIT(init_task.pending.list),.signal = {{0}}},.blocked = {{0}},.alloc_lock = __SPIN_LOCK_UNLOCKED(init_task.alloc_lock),.journal_info = NULL,INIT_CPU_TIMERS(init_task).pi_lock = __RAW_SPIN_LOCK_UNLOCKED(init_task.pi_lock),.timer_slack_ns = 50000, /* 50 usec default slack */.thread_pid = &init_struct_pid,.thread_group = LIST_HEAD_INIT(init_task.thread_group),.thread_node = LIST_HEAD_INIT(init_signals.thread_head),
#ifdef CONFIG_AUDIT.loginuid = INVALID_UID,.sessionid = AUDIT_SID_UNSET,
#endif
#ifdef CONFIG_PERF_EVENTS.perf_event_mutex = __MUTEX_INITIALIZER(init_task.perf_event_mutex),.perf_event_list = LIST_HEAD_INIT(init_task.perf_event_list),
#endif
#ifdef CONFIG_PREEMPT_RCU.rcu_read_lock_nesting = 0,.rcu_read_unlock_special.s = 0,.rcu_node_entry = LIST_HEAD_INIT(init_task.rcu_node_entry),.rcu_blocked_node = NULL,
#endif
#ifdef CONFIG_TASKS_RCU.rcu_tasks_holdout = false,.rcu_tasks_holdout_list = LIST_HEAD_INIT(init_task.rcu_tasks_holdout_list),.rcu_tasks_idle_cpu = -1,
#endif
#ifdef CONFIG_TASKS_TRACE_RCU.trc_reader_nesting = 0,.trc_reader_special.s = 0,.trc_holdout_list = LIST_HEAD_INIT(init_task.trc_holdout_list),.trc_blkd_node = LIST_HEAD_INIT(init_task.trc_blkd_node),
#endif
#ifdef CONFIG_CPUSETS.mems_allowed_seq = SEQCNT_SPINLOCK_ZERO(init_task.mems_allowed_seq,&init_task.alloc_lock),
#endif
#ifdef CONFIG_RT_MUTEXES.pi_waiters = RB_ROOT_CACHED,.pi_top_task = NULL,
#endifINIT_PREV_CPUTIME(init_task)
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN.vtime.seqcount = SEQCNT_ZERO(init_task.vtime_seqcount),.vtime.starttime = 0,.vtime.state = VTIME_SYS,
#endif
#ifdef CONFIG_NUMA_BALANCING.numa_preferred_nid = NUMA_NO_NODE,.numa_group = NULL,.numa_faults = NULL,
#endif
#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS).kasan_depth = 1,
#endif
#ifdef CONFIG_KCSAN.kcsan_ctx = {.scoped_accesses = {LIST_POISON1, NULL},},
#endif
#ifdef CONFIG_TRACE_IRQFLAGS.softirqs_enabled = 1,
#endif
#ifdef CONFIG_LOCKDEP.lockdep_depth = 0, /* no locks held yet */.curr_chain_key = INITIAL_CHAIN_KEY,.lockdep_recursion = 0,
#endif
#ifdef CONFIG_FUNCTION_GRAPH_TRACER.ret_stack = NULL,.tracing_graph_pause = ATOMIC_INIT(0),
#endif
#if defined(CONFIG_TRACING) && defined(CONFIG_PREEMPTION).trace_recursion = 0,
#endif
#ifdef CONFIG_LIVEPATCH.patch_state = KLP_UNDEFINED,
#endif
#ifdef CONFIG_SECURITY.security = NULL,
#endif
#ifdef CONFIG_SECCOMP_FILTER.seccomp = { .filter_count = ATOMIC_INIT(0) },
#endif
};
EXPORT_SYMBOL(init_task);
四、源码分析
1、设置0号进程PCB
/* 代码位置: /arch/arm64/kernel/head.S *//** Initialize CPU registers with task-specific and cpu-specific context.** Create a final frame record at task_pt_regs(current)->stackframe, so* that the unwinder can identify the final frame record of any task by* its location in the task stack. We reserve the entire pt_regs space* for consistency with user tasks and kthreads.*/.macro init_cpu_task tsk, tmp1, tmp2msr sp_el0, \tskldr \tmp1, [\tsk, #TSK_STACK]add sp, \tmp1, #THREAD_SIZEsub sp, sp, #PT_REGS_SIZEstp xzr, xzr, [sp, #S_STACKFRAME]add x29, sp, #S_STACKFRAMEscs_load_currentadr_l \tmp1, __per_cpu_offsetldr w\tmp2, [\tsk, #TSK_TI_CPU]ldr \tmp1, [\tmp1, \tmp2, lsl #3]set_this_cpu_offset \tmp1.endm/** The following fragment of code is executed with the MMU enabled.** x0 = __pa(KERNEL_START)*/
SYM_FUNC_START_LOCAL(__primary_switched)adr_l x4, init_taskinit_cpu_task x4, x5, x6……bl start_kernelASM_BUG()
SYM_FUNC_END(__primary_switched)
在 __primary_switched
函数中将 init_task
值保存到 sp_el0
寄存器中,然后调用 start_kernel
函数。至此成功将 init_task
设置成 0
号进程的进程控制块,并成功运行 0
号进程。
2、设置栈底魔数
置栈底魔数,用于栈溢出检查。
/* 函数定义在 /init/main.c 中 */asmlinkage __visible void __init __no_sanitize_address __noreturn start_kernel(void)
{char *command_line;char *after_dashes;set_task_stack_end_magic(&init_task);……
}
3、其他配置
详细配置见 Linux
源码。
五、获取当前PCB
/* 函数定义在 arch/arm64/include/asm/current.h 文件中 *//** We don't use read_sysreg() as we want the compiler to cache the value where* possible.*/
static __always_inline struct task_struct *get_current(void)
{unsigned long sp_el0;asm ("mrs %0, sp_el0" : "=r" (sp_el0));return (struct task_struct *)sp_el0;
}#define current get_current()
相关文章:
基于aarch64分析kernel源码 五:idle进程(0号进程)
一、参考 linux — 0号进程,1号进程,2号进程 - 流水灯 - 博客园 (cnblogs.com) Linux0号进程,1号进程,2号进程_0号进程和1号进程-CSDN博客 二、idle进程的创建流程 start_kernel --> arch_call_rest_init --> rest_init…...

【Linux】 vi / vim 使用
天天用vim 或者vi 。看着大佬用的很6 。我们却用的很少。今天咱们一起系统学习一下。 vi / vim 发展史 vi 是一款由加州大学伯克利分校,Bill Joy研究开发的文本编辑器。 vim Vim是一个类似于Vi的高度可定制的文本编辑器,在Vi的基础上改进和增加了很多…...

Leetcode hot 100之双指针(快慢指针、滑动窗口)
目录 数组 有序的平方仍有序 删除/覆盖元素 移动零:交换slow和fast 滑动窗口:最短的连续子串(r可行解->l--最短解) 最小长度的子数组 求和:sort、l i 1, r len - 1 三数之和abctarget 四数之和abcdtarg…...

Bridge Champ助力我国桥牌阔步亚运, Web3游戏为传统项目注入创新活力
本届杭州亚运会,中国桥牌队表现杰出,共斩获1金1银1铜佳绩,其中女子团体夺得冠军,混合团体获得亚军。这充分展现了我国桥牌的实力,也彰显了桥牌作为亚运会体育竞技项目的影响力。与此同时,Web3游戏Bridge Champ为传统桥牌项目带来创新模式,将有望推动桥牌运动在亚运舞台上焕发新…...

云原生微服务 第六章 Spring Cloud中使用OpenFeign
系列文章目录 第一章 Java线程池技术应用 第二章 CountDownLatch和Semaphone的应用 第三章 Spring Cloud 简介 第四章 Spring Cloud Netflix 之 Eureka 第五章 Spring Cloud Netflix 之 Ribbon 第六章 Spring Cloud 之 OpenFeign 文章目录 系列文章目录前言1、OpenFeign的实现…...
uniapp-vue3 抖音小程序开发(上线项目开源)
最近公司临时接一个项目来接手别人的流量,项目比较小,时间比较赶。 需求:一个答题小程序,通过答题来实现性格测算和分析。 之前开发过支付宝小程序和微信小程序,这次是首次开发抖音小程序,老板要求只能下…...

基于微信小程序的个人健康数据管理平台设计与实现(源码+lw+部署文档+讲解等)
文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序(小蔡coding)有保障的售后福利 代码参考源码获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…...

真香!Jenkins 主从模式解决问题So Easy~
01.Jenkins 能干什么 Jenkins 是一个开源软件项目,是基于 Java 开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件项目可以进行持续集成。 中文官网:https://jenkins.io/zh/ 0…...

Win10系统打开组策略编辑器的两种方法
组策略编辑器是Win10电脑中很实用的工具,它可以帮助用户管理和设置计算机的安全性、网络连接、软件安装等各种策略。但是,很多新手用户不知道打开Win10电脑中组策略编辑器的方法步骤,下面小编给大家介绍两种简单的方法,帮助打开快…...
git 的行结束符
CR (Carriage Return) 表示<回车>LF (Line Feed) 表示<换行> 1. 不同系统的行结束符 系统名称行结束符意义释义git line endings选项DOS / Windows\r\nCRLF‘\r’是使光标移动到行首 ’\n’是使光标下移一行Windows-styleMacOS\rCRreturnAs-isUNIX / Linux\nLFne…...

buuctf PWN warmup_csaw_2016
下载附件,IDA查看 发现直接有显示flag函数 int sub_40060D() {return system("cat flag.txt"); }查看程序起始地址0x40060D ; Attributes: bp-based framesub_40060D proc near ; __unwind { push rbp mov rbp, rsp mov edi, offset comman…...

C++中的对象切割(Object slicing)问题
在C中,当我们把派生类对象向上强制转型为基类对象时,会造成对象切割(Object slicing)问题。 请看下面示例代码: #include <iostream> using namespace std;class CBase { public:virtual ~CBase() default;v…...

VxeTable 表格组件推荐
VxeTable 表格组件推荐 https://vxetable.cn 在前端开发中,表格组件是不可或缺的一部分,它们用于展示和管理数据,为用户提供了重要的数据交互功能。VxeTable 是一个优秀的 Vue 表格组件,它提供了丰富的功能和灵活的配置选项&…...

好消息:用 vue3+layui 共同铸造我们新的项目
前言: layui这个框架不知道多少人还在关注着,记得第一次接触它是在18年,后来随着vue,react的盛行,jquerylayui的模式受到了特别大的冲击,后来作者都放弃维护他的官方网站,转而在github/gitee上做…...
JS中 split(/s+/) 和 split(‘ ‘)的区别以及split()详细解法,字符串分割正则用法
博主: http://t.csdnimg.cn/e4gDi split用法详解: http://t.csdnimg.cn/6logr...
MySQL性能调优
🙈作者简介:练习时长两年半的Java up主 🙉个人主页:程序员老茶 🙊 ps:点赞👍是免费的,却可以让写博客的作者开兴好久好久😎 📚系列专栏:Java全栈,…...

如何解决openal32.dll丢失,有什么办法解决
你第一次知道openal32.dll文件是在什么情况下,你了解过openal32.dll文件吗?如果电脑中openal32.dll丢失有什么办法可以解决,今天就教大家如何解决openal32.dll丢失,都有哪些办法可以解决openal32.dll丢失。 一.openal3…...
Nginx 如何配置http server 、负载均衡(反向代理)
目录 1. 关于 Nginx2. 配置http server3. 配置负载均衡 本文主要介绍 Nginx中如何配置 http server,负载均衡(反向代理)。 1. 关于 Nginx Nginx是一个开源的、高性能的、稳定的、简单的、功能丰富的HTTP和反向代理服务器,也可以用作IMAP/POP3/SMTP代理…...

windows docker desktop配置加速地址
目录 为什么常见加速地址在docker desktop上配置 为什么 https://hub.docker.com 是官方的镜像仓库地址,但是它的服务器地址是在国外,有时候访问和下载的速度差强人意。不过好在,我们可以进行远程仓库的设置,将仓库镜像地址设置为…...

戏剧影视设计制作虚拟仿真培训课件提升学生的参与感
说起影视制作,知名的影视制片人寥寥无几,大多数人还在依靠摄影机拍摄实景或搭建实体场景来不断精进场景布局和导演效果,成本高、投入人员多且周期长,随着VR虚拟现实技术的不断发展,利用VR模拟仿真技术进行影视制作实操…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...

shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...