加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專(zhuān)業(yè)用戶(hù)
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

Linux 內(nèi)核啟動(dòng)流程之 start_kernel

2023/01/03
1949
閱讀需 22 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

上次我們寫(xiě)過(guò)了 Linux 啟動(dòng)詳細(xì)流程,這次單獨(dú)解析 start_kernel 函數(shù)。

如下請(qǐng)參考注釋?zhuān)?/p>

Linux kernel-6.1/init/main.c

asmlinkage?__visible?void?__init?__no_sanitize_address?start_kernel(void)
{
?char?*command_line;
?char?*after_dashes;

?set_task_stack_end_magic(&init_task);/*設(shè)置任務(wù)棧結(jié)束魔術(shù)數(shù),用于棧溢出檢測(cè)*/
?smp_setup_processor_id();/*跟?SMP?有關(guān)(多核處理器),設(shè)置處理器?ID*/
?debug_objects_early_init();/*?做一些和?debug?有關(guān)的初始化?*/
?init_vmlinux_build_id();

?cgroup_init_early();/*?cgroup?初始化,cgroup?用于控制?Linux?系統(tǒng)資源*/

?local_irq_disable();/*?關(guān)閉當(dāng)前?CPU?中斷?*/
?early_boot_irqs_disabled?=?true;

?/*
??*?Interrupts?are?still?disabled.?Do?necessary?setups,?then
??*?enable?them.
??*?中斷關(guān)閉期間做一些重要的操作,然后打開(kāi)中斷
??*/
?boot_cpu_init();/*?跟?CPU?有關(guān)的初始化?*/
?page_address_init();/*?頁(yè)地址相關(guān)的初始化?*/
?pr_notice("%s",?linux_banner);/*?打印?Linux?版本號(hào)、編譯時(shí)間等信息?*/
?early_security_init();
?
?/*?系統(tǒng)架構(gòu)相關(guān)的初始化,此函數(shù)會(huì)解析傳遞進(jìn)來(lái)的
?* ATAGS 或者設(shè)備樹(shù)(DTB)文件。會(huì)根據(jù)設(shè)備樹(shù)里面
?*?的?model?和?compatible?這兩個(gè)屬性值來(lái)查找
?* Linux 是否支持這個(gè)單板。此函數(shù)也會(huì)獲取設(shè)備樹(shù)
?*?中?chosen?節(jié)點(diǎn)下的?bootargs?屬性值來(lái)得到命令
?*?行參數(shù),也就是?uboot?中的?bootargs?環(huán)境變量的
?*?值,獲取到的命令行參數(shù)會(huì)保存到?command_line?中
?*/
?setup_arch(&command_line);
?setup_boot_config();
?setup_command_line(command_line);/*?存儲(chǔ)命令行參數(shù)?*/
?
?/*?如果只是?SMP(多核?CPU)的話(huà),此函數(shù)用于獲取
?* CPU 核心數(shù)量,CPU 數(shù)量保存在變量 nr_cpu_ids 中。
?*/
?setup_nr_cpu_ids();
?setup_per_cpu_areas();/*?在?SMP?系統(tǒng)中有用,設(shè)置每個(gè)?CPU?的?per-cpu?數(shù)據(jù)?*/
?smp_prepare_boot_cpu();?/*?arch-specific?boot-cpu?hooks?*/
?boot_cpu_hotplug_init();

?build_all_zonelists(NULL);/*?建立系統(tǒng)內(nèi)存頁(yè)區(qū)(zone)鏈表?*/
?page_alloc_init();/*?處理用于熱插拔?CPU?的頁(yè)?*/

?/*?打印命令行信息?*/?
?pr_notice("Kernel?command?line:?%sn",?saved_command_line);
?/*?parameters?may?set?static?keys?*/
?jump_label_init();
?parse_early_param();/*?解析命令行中的?console?參數(shù)?*/
?after_dashes?=?parse_args("Booting?kernel",
??????static_command_line,?__start___param,
??????__stop___param?-?__start___param,
??????-1,?-1,?NULL,?&unknown_bootoption);
?print_unknown_bootoptions();
?if?(!IS_ERR_OR_NULL(after_dashes))
??parse_args("Setting?init?args",?after_dashes,?NULL,?0,?-1,?-1,
??????NULL,?set_init_arg);
?if?(extra_init_args)
??parse_args("Setting?extra?init?args",?extra_init_args,
??????NULL,?0,?-1,?-1,?NULL,?set_init_arg);

?/*?Architectural?and?non-timekeeping?rng?init,?before?allocator?init?*/
?random_init_early(command_line);

?/*
??*?These?use?large?bootmem?allocations?and?must?precede
??*?kmem_cache_init()
??*/
?setup_log_buf(0);/*?設(shè)置?log?使用的緩沖區(qū)*/
?vfs_caches_init_early();?/*?預(yù)先初始化?vfs(虛擬文件系統(tǒng))的目錄項(xiàng)和索引節(jié)點(diǎn)緩存*/
?sort_main_extable();/*?定義內(nèi)核異常列表?*/
?trap_init();/*?完成對(duì)系統(tǒng)保留中斷向量的初始化?*/
?mm_init();/*?內(nèi)存管理初始化?*/

?ftrace_init();

?/*?trace_printk?can?be?enabled?here?*/
?early_trace_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();/*?初始化調(diào)度器,主要是初始化一些結(jié)構(gòu)體?*/

?if?(WARN(!irqs_disabled(),
???"Interrupts?were?enabled?*very*?early,?fixing?itn"))
??local_irq_disable();/*?檢查中斷是否關(guān)閉,如果沒(méi)有的話(huà)就關(guān)閉中斷?*/
?radix_tree_init();/*?基數(shù)樹(shù)相關(guān)數(shù)據(jù)結(jié)構(gòu)初始化?*/
?maple_tree_init();

?/*
??*?Set?up?housekeeping?before?setting?up?workqueues?to?allow?the?unbound
??*?workqueue?to?take?non-housekeeping?into?account.
??*/
?housekeeping_init();

?/*
??*?Allow?workqueue?creation?and?work?item?queueing/cancelling
??*?early.??Work?item?execution?depends?on?kthreads?and?starts?after
??*?workqueue_init().
??*/
?workqueue_init_early();

?rcu_init();/*?初始化?RCU,RCU?全稱(chēng)為?Read?Copy?Update(讀-拷貝修改)?*/

?/*?Trace?events?are?available?after?this?*/
?trace_init();/*?跟蹤調(diào)試相關(guān)初始化?*/

?if?(initcall_debug)
??initcall_debug_enable();

?context_tracking_init();
?/*?init?some?links?before?init_ISA_irqs()?*/
?
?/*?初始中斷相關(guān)初始化,主要是注冊(cè)?irq_desc?結(jié)構(gòu)體變
?*?量,因?yàn)?Linux 內(nèi)核使用 irq_desc 來(lái)描述一個(gè)中斷。
?*/
?early_irq_init();
?init_IRQ();/*?中斷初始化?*/
?tick_init();/*?tick?初始化?*/
?rcu_init_nohz();
?init_timers();/*?初始化定時(shí)器?*/
?srcu_init();
?hrtimers_init();/*?初始化高精度定時(shí)器?*/
?softirq_init();/*?軟中斷初始化?*/
?timekeeping_init();
?time_init();/*?初始化系統(tǒng)時(shí)間?*/

?/*?This?must?be?after?timekeeping?is?initialized?*/
?random_init();

?/*?These?make?use?of?the?fully?initialized?rng?*/
?kfence_init();
?boot_init_stack_canary();

?perf_event_init();
?profile_init();
?call_function_init();
?WARN(!irqs_disabled(),?"Interrupts?were?enabled?earlyn");

?early_boot_irqs_disabled?=?false;
?local_irq_enable();/*?使能中斷?*/

?kmem_cache_init_late();/*?slab?初始化,slab?是?Linux?內(nèi)存分配器?*/

?/*
??*?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.
??*/
?/*?初始化控制臺(tái),之前?printk?打印的信息都存放
??*?緩沖區(qū)中,并沒(méi)有打印出來(lái)。只有調(diào)用此函數(shù)
??*?初始化控制臺(tái)以后才能在控制臺(tái)上打印信息。
??*/
?console_init();
?if?(panic_later)
??panic("Too?many?boot?%s?vars?at?`%s'",?panic_later,
????????panic_param);

?lockdep_init();

?/*
??*?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();/*?鎖自測(cè)?*/?

?/*
??*?This?needs?to?be?called?before?any?devices?perform?DMA
??*?operations?that?might?use?the?SWIOTLB?bounce?buffers.?It?will
??*?mark?the?bounce?buffers?as?decrypted?so?that?their?usage?will
??*?not?cause?"plain-text"?data?to?be?decrypted?when?accessed.
??*/
?mem_encrypt_init();

#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
?setup_per_cpu_pageset();
?numa_policy_init();
?acpi_early_init();
?if?(late_time_init)
??late_time_init();
?sched_clock_init();
?/*?測(cè)定?BogoMIPS?值,可以通過(guò)?BogoMIPS?來(lái)判斷?CPU?的性能
?* BogoMIPS 設(shè)置越大,說(shuō)明 CPU 性能越好。
?*/
?calibrate_delay();
?pid_idr_init();
?anon_vma_init();/*?生成?anon_vma?slab?緩存?*/?
#ifdef?CONFIG_X86
?if?(efi_enabled(EFI_RUNTIME_SERVICES))
??efi_enter_virtual_mode();
#endif
?thread_stack_cache_init();
?cred_init();/*?為對(duì)象的每個(gè)用于賦予資格(憑證)?*/
?fork_init();/*?初始化一些結(jié)構(gòu)體以使用?fork?函數(shù)?*/
?proc_caches_init();/*?給各種資源管理結(jié)構(gòu)分配緩存?*/
?uts_ns_init();
?key_init();/*?初始化密鑰?*/
?security_init();/*?安全相關(guān)初始化?*/
?dbg_late_init();
?net_ns_init();
?vfs_caches_init();/*?虛擬文件系統(tǒng)緩存初始化?*/
?pagecache_init();
?signals_init();/*?初始化信號(hào)?*/
?seq_file_init();
?proc_root_init();/*?注冊(cè)并掛載?proc?文件系統(tǒng)?*/
?nsfs_init();
?/*?初始化?cpuset,cpuset?是將?CPU?和內(nèi)存資源以邏輯性
?*?和層次性集成的一種機(jī)制,是?cgroup?使用的子系統(tǒng)之一
?*/
?cpuset_init();
?cgroup_init();/*?初始化?cgroup?*/
?taskstats_init_early();/*?進(jìn)程狀態(tài)初始化?*/
?delayacct_init();

?poking_init();
?check_bugs();/*?檢查寫(xiě)緩沖一致性?*/

?acpi_subsystem_init();
?arch_post_acpi_subsys_init();
?kcsan_init();

?/*?Do?the?rest?non-__init'ed,?we're?now?alive?*/
?/*?調(diào)用?rest_init?函數(shù)?*/
?/*?創(chuàng)建?init、kthread、idle?線(xiàn)程?*/
?arch_call_rest_init();

?prevent_tail_call_optimization();
}

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

研究生在讀,熟悉硬件、STM32單片機(jī)、嵌入式Linux。已收獲小米、聯(lián)發(fā)科、浙江大華、上能電氣、英威騰、匯川技術(shù)、格力、富士康等大廠offer。在這里分享求職經(jīng)驗(yàn)、嵌入式學(xué)習(xí)規(guī)劃、考研、嵌入式Linux技術(shù)文章等。