1.一文了解Linux内核启动流程
2.linux0.11源码分析-fork进程
3.Linux内核源码解析---cgroup实现之整体架构与初始化
4.Nginx源码阅读(五):启动前的进程进程准备
5.Nginx源码分析 - 主流程篇 - Nginx的启动流程
一文了解Linux内核启动流程
本文以Linux3.版本源码为例分析其启动流程。不同版本的源码启动代码虽然存在差异,但核心的进程进程启动逻辑与理念保持不变。
内核映像在内存中加载并获取控制权后,源码启动流程启动。进程进程由于内核映像是源码股市软件源码以压缩形式存储的,而非可执行文件,进程进程因此首要步骤是源码自解压内核映像。
内核在编译时生成vmliunx,进程进程通常会被压缩成zImage(小于KB的源码小内核)或bzImage(大于KB的大内核)。这些内核映像的进程进程头部包含解压缩程序。
通过查找vmlinux文件的源码链接脚本(vmlinux.lds)中的系统启动入口函数,通常在linux/arch/arm/boot/compressed目录下的进程进程Makefile中找到这一信息。
得到的源码内核入口函数为stext(linux/arch/arm/kernel/head.S),这是进程进程启动流程的关键环节。
内核启动阶段,通过查找标签__mmap_switched的位置(/linux/arch/arm/kernel/head-common.S),实现内存映射的切换。
从start_kernel函数开始,内核进入C语言部分,执行内核的大部分初始化任务。函数位于/lint/init/Main.c。
start_kernel函数涵盖了大量初始化工作,其中包括系统调用、内存管理、进程调度、设备驱动等核心模块的初始化。最终,源码技术app函数调用rest_init()函数完成剩余初始化。
kernel_init函数负责设备驱动程序的初始化,并调用init_post函数启动用户进程。现代版本的内核已经将init_post函数的特定任务整合到kernel_init中。
在内核初始化接近尾声时,free_initmem函数清除内存的__init_begin至__init_end区间数据。
内核启动后,运行自己的第一个用户空间应用程序_init,它是使用标准C库编译的第一个程序,进程ID为1。
_init执行其他必需的进程启动,以使系统进入全面可用的状态。
以下是内核启动流程图,以直观展示启动过程的关键步骤和顺序。
linux0.源码分析-fork进程
在操作系统中,Linux0.源码中的fork函数执行流程分为启动和系统调用两个阶段。启动阶段首先在init/main.c中执行init用于启动shell,让用户执行命令。
在include/unistd.h中定义了宏,表示将__NR_fork的值复制给eax寄存器,并将_res与eax绑定。使用int 0x中断后,系统调用函数system_call被调用,从sys_call_table中找到对应的函数执行。fork函数执行时,操作系统会在内核栈里保存相关寄存器,准备中断返回。编程源码实例
接着,操作系统通过int调用system_call,在kernel/system_call.s中执行call _sys_call_table(,%eax,4)指令。内核栈中,因为是段内跳转,所以cs不需要入栈。ip指向call指令的下一句代码。执行call指令进入系统调用表。
在includ/linux/sys.h中,系统调用表是一个数组,根据eax即系统函数编号找到对应的函数执行。对于fork,__NR_fork值2被放入eax寄存器,%eax * 4找到sys_fork。执行sys_fork后,调用find_empty_process函数找到可用的进程号,并放入eax寄存器返回。
接着,系统调用执行copy_process函数建立新进程结构体并复制数据。新进程的ip出栈,执行完copy_process后,系统调用返回,内核栈状态改变。此阶段最后通过iret指令弹出寄存器,恢复中断前状态。
总结,fork函数通过复制当前进程结构体、赚点点源码处理信号并初始化新进程,实现父进程与子进程的创建与共享。子进程返回值为0,父进程返回新子进程的pid。通过fork函数的执行,操作系统能够高效地创建进程,实现多任务处理。
Linux内核源码解析---cgroup实现之整体架构与初始化
cgroup在年由Google工程师开发,于年被融入Linux 2.6.内核。它旨在管理不同进程组,监控一组进程的行为和资源分配,是Docker和Kubernetes的基石,同时也被高版本内核中的LXC技术所使用。本文基于最早融入内核中的代码进行深入分析。
理解cgroup的核心,首先需要掌握其内部的常用术语,如子系统、层级、cgroupfs_root、cgroup、css_set、cgroup_subsys_state、cg_cgroup_link等。子系统负责控制不同进程的行为,例如CPU子系统可以控制一组进程在CPU上执行的时间占比。层级在内核中表示为cgroupfs_root,一个层级控制一批进程,Mjresh源码 ios层级内部绑定一个或多个子系统,每个进程只能在一个层级中存在,但一个进程可以被多个层级管理。cgroup以树形结构组织,每一棵树对应一个层级,层级内部可以关联一个或多个子系统。
每个层级内部包含的节点代表一个cgroup,进程结构体内部包含一个css_set,用于找到控制该进程的所有cgroup,多个进程可以共用一个css_set。cgroup_subsys_state用于保存一系列子系统,数组中的每一个元素都是cgroup_subsys_state。cg_cgroup_link收集不同层级的cgroup和css_set,通过该结构可以找到与之关联的进程。
了解了这些概念后,可以进一步探索cgroup内部用于结构转换的函数,如task_subsys_state、find_existing_css_set等,这些函数帮助理解cgroup的内部运作。此外,cgroup_init_early和cgroup_init函数是初始化cgroup的关键步骤,它们负责初始化rootnode和子系统的数组,为cgroup的使用做准备。
最后,需要明确Linux内一切皆文件,cgroup基于VFS实现。内核启动时进行初始化,以确保系统能够正确管理进程资源。cgroup的初始化过程分为早期初始化和常规初始化,其中早期初始化用于准备cpuset和CPU子系统,确保它们在系统运行时能够正常工作。通过这些步骤,我们可以深入理解cgroup如何在Linux内核中实现资源管理和进程控制。
Nginx源码阅读(五):启动前的准备
在 Nginx 启动前,一系列初始化流程和变量设定至关重要。这些准备工作确保 Nginx 正常运行,高效管理资源并优化性能。接下来,我们将分步骤详细介绍 Nginx 启动前的准备过程。1. ngx_os_init 获取系统级资源
ngx_os_init 负责初始化操作系统级资源,将关键参数赋值给全局变量。这些参数包括页面大小、缓存行大小、最大套接字数等。 系统级参数获取依赖于 sysconf 函数,它用于查询系统特定参数,如 CPU 核心数量、内存大小、进程打开的最大文件数等。 _SC_NPROCESSORS_CONF返回 CPU 核心数量,包括不可用核心。
_SC_NPROCESSORS_ONLN返回系统中可用的 CPU 核心数量。
_SC_PAGESIZE表示系统页面大小(字节单位)。
_SC_PHYS_PAGES表示系统物理内存页数。
_SC_OPEN_MAX表示进程可以打开的最大文件数。
_SC_GETPW_R_SIZE_MAX表示 getpwuid_r 函数使用的缓冲区大小限制。
另一个关键函数 ngx_cpuinfo 用于获取 CPU 的 L2 缓存行大小。理解 CPU 缓存级别有助于优化 Nginx 性能。L1 缓存位于 CPU 核心内,是最快的缓存层。
L2 缓存在 CPU 芯片上,但比 L1 缓存距离核心更远。
L3 缓存位于 CPU 外部,速度仅次于内存,但大小较大。
不同 CPU 的缓存大小差异显著,如图所示。L1 和 L2 缓存通常在 CPU 核之间不共享,而 L3 缓存为所有核心共享。 此外,getrlimit 和 setrlimit 函数用于查询和更改进程资源限制。rlimit 结构体参数用于指定资源限制,如最大句柄数,即最大可创建的套接字数量。2. ngx_crc_table_init 初始化 CRC 表
此函数初始化循环冗余校验(CRC)表,确保计算效率。通过将指向校验表格的指针ngx_crc_table_short 对齐至缓存行大小,提高性能。 CRC 是一种用于检测数据传输或保存错误的校验方法。生成的数字附加至数据后,接收端进行验证以确保数据未变。具体原理可参考网络资料。3. ngx_add_inherited_sockets 继承套接字
在平滑升级场景下,ngx_add_inherited_sockets 用于继承原有监听套接字。通过环境变量 NGINX 获取套接字信息,将其加入 init_cycle 的 listening 数组。完成继承后,设置全局变量 ngx_inherited 为 1。 此函数仅在平滑升级过程中使用,通常情况下无需执行。因此,我们不对该函数进行过多讨论。Nginx源码分析 - 主流程篇 - Nginx的启动流程
深入解析Nginx的核心,理解基础数据结构对源码解读至关重要。主流程的精髓隐藏在nginx.c的main()函数中,它启动的每一个步骤都如同乐谱上的一段旋律,优雅而有序。启动乐章
首先,指挥棒落在ngx_get_options上,它如同乐团指挥,优雅地解析启动命令行参数。接着,ngx_time_init、ngx_getpid和ngx_log_init依次登场,为时间、进程标识和日志设置调音。它们共同完成了一次细致入微的初始化过程,为接下来的演出铺平道路。 紧接着,ngx_init_cycle指挥全局变量的诞生,包括一致性哈希表的初始化,以及处理系统变量的微妙操作。随后,它引导我们进入一个关键环节:继承socket,初始化模块,设置信号处理,配置文件的获取和pid文件的创建,如同交响乐中的序曲,为后续的进程管理做准备。乐章高潮
当进入ngx_master_process_cycle部分,主进程的魔法开始显现。它如魔术师般,通过创建子进程,让各个模块和事件监听开始各自的旋律。在这里,每个参数处理都如同精心编排的音符,确保演奏的和谐。关键步骤
在ngx_get_options中,启动命令参数如-s stop/start/restart的解读,是理解Nginx行为的关键。而在幕后,ngx_save_argv负责存储这些参数,ngx_process_options则如同指挥家,将参数的魔力注入到ngx_cycle的结构中。 特别关注的全局变量,如ngx_show_help、ngx_conf_file,它们是Nginx运行的调色板。ngx_save_argv和ngx_process_options如同调色师,精心调配每个参数的色彩。模块初始化的序曲
ngx_preinit_modules是模块世界的序曲,它负责初始化配置路径、处理参数,以及配置文件的定位。在这里,每个动作都精确而有序,确保每个模块都能在正确的时间奏响属于自己的旋律。 在ngx_module.c中,模块编号的分配和配置文件的处理,如同管弦乐队的编排,确保每个乐器都能和谐共奏。而创建PID文件的函数ngx_create_pidfile则如定音锤,为整个系统敲定最后的音符。 每个重要模块,如ngx_add_inherited_sockets、ngx_init_cycle、ngx_signal_process和ngx_master_process_cycle,都在各自的角色中发挥着不可或缺的作用,共同编织出Nginx启动的华美乐章。2024-12-22 23:041757人浏览
2024-12-22 22:382334人浏览
2024-12-22 22:211767人浏览
2024-12-22 21:172605人浏览
2024-12-22 20:502000人浏览
2024-12-22 20:351810人浏览
中国消费者报北京讯(记者任震宇)为应对新型冠状病毒感染肺炎疫情防控提供保障,市场监管总局印发《关于坚决维护防疫用品市场价格秩序的公告》,指导并督促各级市场监管部门加强对口罩等防疫用品的价格监督检查,查
中国消费者报武汉讯杨杰 记者吴采平)为守护广大师生“舌尖上的安全”,8月30日,湖北省武汉市市场监管局联合公安、卫健委等部门推进“守底线、查隐患、保安全”专项行动,开展学校食堂及校园周边食品经营单位食