基于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模拟仿真技术进行影视制作实操…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
