源码
解释1
-
static int __ref kernel_init(void *unused)
: 声明一个静态整型函数kernel_init()
,该函数不会被其他文件访问,使用__ref
标记表示该函数是可重定位的,并且该函数不需要任何参数。 -
wait_for_completion(&kthreadd_done);
: 等待kthreadd
线程完成初始化,wait_for_completion()
函数会阻塞当前进程,直到指定的完成对象完成。 -
kernel_init_freeable();
: 调用kernel_init_freeable()
函数进行内核初始化,该函数包括了内核的大部分初始化工作。 -
async_synchronize_full();
: 在进行异步初始化代码之前,需要进行同步操作,以确保所有异步初始化代码都已经完成。 -
kprobe_free_init_mem();
: 释放kprobe初始化时申请的内存空间。
kprobe是一种用于动态跟踪内核函数调用的机制,在初始化阶段需要申请一些内存空间来存储相关的数据结构,该函数用于在初始化完成后释放这些内存空间。 -
ftrace_free_init_mem();
: 释放ftrace初始化时申请的内存空间。 -
kgdb_free_init_mem();
: 释放kgdb初始化时申请的内存空间。 -
free_initmem();
: 释放内核初始化时申请的内存空间。 -
mark_readonly();
: 将内核只读化,以提高系统的安全性和稳定性。
这段代码是Linux内核启动过程中的一个重要函数rest_init()
。该函数在内核初始化完成后,用于启动用户空间的第一个进程,即init
进程。该函数会依次尝试多种方式来启动init
进程,直到找到一个可行的方式。具体解释如下:
解释2
pti_finalize();
: 更新用户空间的页表,以完成PTI。
PTI(Page Table Isolation)是一种安全机制,用于防止针对Meltdown漏洞的攻击。Meltdown漏洞是一种硬件漏洞,可以允许攻击者在不受限制的情况下读取内核内存中的敏感信息。为了解决这个问题,Linux内核引入了PTI机制,该机制将内核和用户空间的页表分离,以防止攻击者利用Meltdown漏洞来访问内核内存。
在Linux内核中,pti_finalize()
函数用于更新用户空间的页表,以完成PTI机制。具体而言,该函数会将内核和用户空间的页表分离,并将用户空间的页表设置为只读状态,以防止恶意程序修改页表,从而绕过PTI机制。此外,pti_finalize()
函数还会执行一些其他的安全检查和操作,以确保PTI机制能够正常工作。
pti_finalize()
函数是Linux内核中用于完成PTI机制的重要函数,它通过更新用户空间的页表来分离内核和用户空间的页表,并确保PTI机制能够正常工作,从而提高系统的安全性和稳定性。
2. system_state = SYSTEM_RUNNING;
: 将系统状态设置为SYSTEM_RUNNING
,表示内核已经完成初始化,可以开始运行用户空间的进程。
numa_default_policy();
: 设置NUMA内存分配策略为默认值。
NUMA(Non-Uniform Memory Access)是一种计算机内存架构,它允许多个处理器访问共享内存,以提高系统的性能和可扩展性。在NUMA系统中,每个处理器都有自己的本地内存,同时也可以访问其他处理器的远程内存。为了更好地管理内存,Linux内核提供了NUMA内存分配策略,用于确定在NUMA系统中如何分配内存。
在Linux内核中,numa_default_policy()
函数用于设置NUMA内存分配策略为默认值。具体而言,该函数会根据系统的硬件配置和内核参数来确定NUMA内存分配策略,并将其设置为默认值。在设置NUMA内存分配策略之前,该函数还会执行一些其他的操作,如检查NUMA节点的状态、初始化NUMA节点的内存管理器等。
总之,numa_default_policy()
函数是Linux内核中用于设置NUMA内存分配策略的重要函数,它根据系统的硬件配置和内核参数来确定NUMA内存分配策略,并将其设置为默认值,以提高系统的性能和可扩展性。
4. rcu_end_inkernel_boot();
: 结束内核启动期间的RCU初始化。
-
do_sysctl_args();
: 处理内核启动参数中的sysctl参数。 -
if (ramdisk_execute_command) {...}
: 如果内核启动参数中指定了initrd
命令,则执行该命令。 -
if (execute_command) {...}
: 如果内核启动参数中指定了init
命令,则执行该命令。 -
if (CONFIG_DEFAULT_INIT[0] != '\0') {...}
: 如果内核配置文件中指定了默认的init
命令,则执行该命令。 -
if (!try_to_run_init_process("/sbin/init") || ...
: 依次尝试尝试多种方式来启动init
进程,包括/sbin/init
、/etc/init
、/bin/init
和/bin/sh
等。如果所有方式都失败,则触发内核恐慌,提示用户使用init=
选项来指定init
进程。
rest_init()
函数是Linux内核启动过程中的一个重要函数,用于启动用户空间的第一个进程,即init
进程。在启动init
进程之前,该函数会完成一系列必要的初始化工作,以确保内核能够正常运行。