asmlinkage __visible void __init start_kernel(void)
{
char *command_line;
char *after_dashes;
set_task_stack_end_magic(&init_task);
/*
* 仅在结构为SPAC时执行
* 为其他arch时不执行任何操作
*/
smp_setup_processor_id();
/*
* 已定义CONFIG_DEBUG_OBJECTS时
* 初始化以追踪内核管理对象
*/
debug_objects_early_init();
/*
* Set up the the initial canary ASAP:
* 理解为防止栈溢出攻击
*/
boot_init_stack_canary();
/*
* 初始化init进程要用的
* cgroup相关数据结构
*/
cgroup_init_early();
/*
* 禁用当前任务的hardirq
*/
local_irq_disable();
early_boot_irqs_disabled = true;
/*
* Interrupts are still disabled. Do necessary setups, then
* enable them
*/
/*
* 有管理CPU的位图
* 将位图执行init_task的CPU标记为1
*/
boot_cpu_init();
/*
* 初始化page_address_pool
* 他通过链表管理page_address_maps
* 对HIGHMEM进行全局管理
*/
page_address_init();
pr_notice("%s", linux_banner);
/*
* 对结构进行设置
* 设置处理器,机器
* 启动时内存分配器等
*/
setup_arch(&command_line);
/*
* 设置显示内存信息的mm_struct
* 属于哪个任务
*/
mm_init_cpumask(&init_mm);
/*
* 将启动加载项传递的命令
* 分为未修正命令行
* 和已执行参数分析的命令行并保存
*/
setup_command_line(command_line);
/*
* 将系统内置CPU数量
* 保存到全局变量nr_cpu_ids
*/
setup_nr_cpu_ids();
/*
* 为内核的内存管理执行初始化
* 只在SMP系统中调用
* UP时不执行任何操作
*/
setup_per_cpu_areas();
boot_cpu_state_init();
/*
* 在与当前执行启动的CPU对应的
* per-cpu(.data.percpu)
* 中注册执行启动的进程
*/
smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */
/*
* 构建借用内存的后台
*/
build_all_zonelists(NULL, NULL);
/*
* 在CPU事件通知链中注册page_alloc_cpu_notify
* 回调函数
* cpu被热插拔时处理与相应
* CPU相关的页和vm_stat值
*/
page_alloc_init();
pr_notice("Kernel command line: %s\n", boot_command_line);
/*用未修正的原参数处理初始参数*/
parse_early_param();
after_dashes = parse_args("Booting kernel",
static_command_line, __start___param,
__stop___param - __start___param,
-1, -1, NULL, &unknown_bootoption);
if (!IS_ERR_OR_NULL(after_dashes))
parse_args("Setting init args", after_dashes, NULL, 0, -1, -1,
NULL, set_init_arg);
jump_label_init();
/*
* These use large bootmem allocations and must precede
* kmem_cache_init()
*/
setup_log_buf(0);
/*生成pid散列表*/
pidhash_init();
/*
* 制作用于dentry缓存和inode缓存
* 的散列表并执行初始化任务
*/
vfs_caches_init_early();
/*
* 实际的异常列表并不聚集在各项
* 而是分散在代码各处
* 因此在链接阶段将其集中
*/
sort_main_extable();
//
trap_init();
mm_init();
/*
* Set up the scheduler prior starting any interrupts (such as the
* timer interrupt). Full topology setup happens at smp_init()
* time - but meanwhile we still have a functioning scheduler.
*/
/*
* 调度程序需要的数据结构进行初始化
*/
sched_init();
/*
* Disable preemption - early bootup scheduling is extremely
* fragile until we cpu_idle() for the first time.
*/
/*禁用抢占*/
preempt_disable();
if (WARN(!irqs_disabled(),
"Interrupts were enabled *very* early, fixing it\n"))
local_irq_disable();
/*
* 管理整数ID编号的服务
* 未实现POSIX计数器相关系统而编写
*/
idr_init_cache();
/*
* 初始化联机CPU的RCU数据结构
* 注册面向RCU_SOFTIRQ的回调函数
* 在cpu_chain中注册notifier block
*/
rcu_init();
/* trace_printk() and trace points may be used after this */
trace_init();
context_tracking_init();
/*
* 初始化radix树
* 用于搜索存在于内存的所有页
*/
radix_tree_init();
/* init some links before init_ISA_irqs() */
/*
* 初始化用于中断的数据
*/
early_irq_init();
/*
* 初始化用于技术全体终端的irq_desc
* 结构体,按终端调用初始化函数
* 以初始化中断
*/
init_IRQ();
/*
* 注册用于处理时钟设备发出时间的处理器
*/
tick_init();
rcu_init_nohz();
/*为使用计时器而执行初始化任务*/
init_timers();
/*初始化高精度计时器*/
hrtimers_init();
/*初始化底半部*/
softirq_init();
timekeeping_init();
/*
* 初始化硬件时钟并设置计时器中断周期
* 注册发生中断时要调用的处理器
*/
time_init();
sched_clock_postinit();
printk_nmi_init();
perf_event_init();
/*
* 分配分析代码区域时使用的内存
* 将prof_cpu_mask设置未cpu_possible_mask
*/
profile_init();
call_function_init();
WARN(!irqs_disabled(), "Interrupts were enabled early\n");
early_boot_irqs_disabled = false;
local_irq_enable();
/*激活slab内存分配器*/
kmem_cache_init_late();
/*
* HACK ALERT! This is early. We're enabling the console before
* we've done PCI setups etc, and console_init() must be aware of
* this. But we do want output early, in case something goes wrong.
*/
/*为使用控制台进行简单初始化*/
console_init();
if (panic_later)
panic("Too many boot %s vars at `%s'", panic_later,
panic_param);
/*
* 输出锁依赖信息
*/
lockdep_info();
/*
* Need to run this when irqs are enabled, because it wants
* to self-test [hard/soft]-irqs on/off lock inversion bugs
* too:
*/
/*锁机制自测*/
locking_selftest();
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start && !initrd_below_start_ok &&
page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) {
pr_crit("initrd overwritten (0x%08lx < 0x%08lx) - disabling it.\n",
page_to_pfn(virt_to_page((void *)initrd_start)),
min_low_pfn);
initrd_start = 0;
}
#endif
page_ext_init();
debug_objects_mem_init();
kmemleak_init();
/*在内核启动过程中构建pageset*/
setup_per_cpu_pageset();
/*NUMA系统的内存策略决定内核从哪一个节点分配内存*/
numa_policy_init();
if (late_time_init)
late_time_init();
/*
* 初始化各CPU的sched_clock_data
*/
sched_clock_init();
calibrate_delay();
/*生成用于分配进程标识符的位图*/
pidmap_init();
/*
* 初始化anon_vma数据结构
*/
anon_vma_init();
acpi_early_init();
#ifdef CONFIG_X86
if (efi_enabled(EFI_RUNTIME_SERVICES))
efi_enter_virtual_mode();
#endif
#ifdef CONFIG_X86_ESPFIX64
/* Should be run before the first non-init thread is created */
init_espfix_bsp();
#endif
thread_stack_cache_init();
/*
* 为区分对象有执行执行何种操作的资格
* 按不同用户制作凭证
* 对此进行初始化
*/
cred_init();
/*为进程能够执行fork做准备*/
fork_init();
/*
* 生成用于signal_struct
* sighand_struct,files_struct,fs_struct
* vm_area_struct,mm_struct的kmem_cache
* 并初始化percpu_counter
*/
proc_caches_init();
/*为缓冲缓存所需元数据buffer_head结构体构建slab缓存 */
buffer_init();
/*准备安全密钥*/
key_init();
/*初始化安全框架*/
security_init();
dbg_late_init();
/*初始化VFS中使用的多种缓存*/
vfs_caches_init();
/*初始化以使用信号*/
signals_init();
/* rootfs populating might need page-writeback */
/*
* 初始化以进行周期性页回写
*/
page_writeback_init();
/*
* 注册proc文件系统
* 并生成/初始化相关数据结构
* 在文件系统内生成多个默认项
*/
proc_root_init();
nsfs_init();
/*
* cupset初始化
*/
cpuset_init();
/*
* cgroup初始化
*/
cgroup_init();
/*
* 初始化基于netlink的接口taskstats
* 以在内核中向用户控件传递任务
* 和进程状态信息
*/
taskstats_init_early();
/*
* 执行任务或进程过程中
* 等待特定源代码变为可用状态前
* 为管理延迟信息做准备
*/
delayacct_init();
/*
* 对同意也分配2个不同的虚拟内存
* 并执行写测试
*/
check_bugs();
acpi_subsystem_init();
sfi_init_late();
if (efi_enabled(EFI_RUNTIME_SERVICES)) {
efi_late_init();
efi_free_boot_services();
}
/*
* 修正并可动态追踪所有函数调用
*/
ftrace_init();
/* Do the rest non-__init'ed, we're now alive */
/*
* 启动最后阶段
* 生成init进程 内核线程等
*/
rest_init();
}
linux 4.9--start_kernel
最新推荐文章于 2021-05-26 16:52:06 发布