基于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模拟仿真技术进行影视制作实操…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
