Linux內核啟動分析

来源:http://www.cnblogs.com/zhangchao0515/archive/2016/03/12/5269273.html
-Advertisement-
Play Games

張超《Linux內核分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000 我的代碼可見https://www.shiyanlou.com/courses/reports/986221 在這裡我們用的是linux-3.18.6版本,以下簡寫


張超《Linux內核分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000

我的代碼可見https://www.shiyanlou.com/courses/reports/986221

在這裡我們用的是linux-3.18.6版本,以下簡寫成linux。

start_kernel在 /linux/init/main.c中定義:

這個函數是內核由引導程式引導以後,由自解壓程式解壓以後執行的第一個函數,可以認為是整個內核的入口函數,以後我分析的代碼全部從這個函數開始!

這個函數做的事情相對比較簡單,就是線性的初始化一些內核的基礎機制,如中斷,記憶體管理,進程管理,信號,文件系統,KO等!最後就啟動一個init線程,init線程再讀取文件系統里的init程式,做為系統的第一個進程而存在!

其實,start_kernel函數是0是做為0號進程存在的,它在最後就是空轉CPU:

500asmlinkage __visible void __init start_kernel(void)
501{
502    char *command_line;
503    char *after_dashes;
504
505    /*
506     * Need to run as early as possible, to initialize the
507     * lockdep hash:
508     */
509    lockdep_init();
510    set_task_stack_end_magic(&init_task);
511    smp_setup_processor_id();
512    debug_objects_early_init();
513
514    /*
515     * Set up the the initial canary ASAP:
516     */
517    boot_init_stack_canary();
518
519    cgroup_init_early();
520
521    local_irq_disable();
522    early_boot_irqs_disabled = true;
523
524/*
525 * Interrupts are still disabled. Do necessary setups, then
526 * enable them
527 */
528    boot_cpu_init();
529    page_address_init();
530    pr_notice("%s", linux_banner);
531    setup_arch(&command_line);
532    mm_init_cpumask(&init_mm);
533    setup_command_line(command_line);
534    setup_nr_cpu_ids();
535    setup_per_cpu_areas();
536    smp_prepare_boot_cpu();    /* arch-specific boot-cpu hooks */
537
538    build_all_zonelists(NULL, NULL);
539    page_alloc_init();
540
541    pr_notice("Kernel command line: %s\n", boot_command_line);
542    parse_early_param();
543    after_dashes = parse_args("Booting kernel",
544                  static_command_line, __start___param,
545                  __stop___param - __start___param,
546                  -1, -1, &unknown_bootoption);
547    if (!IS_ERR_OR_NULL(after_dashes))
548        parse_args("Setting init args", after_dashes, NULL, 0, -1, -1,
549               set_init_arg);
550
551    jump_label_init();
552
553    /*
554     * These use large bootmem allocations and must precede
555     * kmem_cache_init()
556     */
557    setup_log_buf(0);
558    pidhash_init();
559    vfs_caches_init_early();
560    sort_main_extable();
561    trap_init();
562    mm_init();
563
564    /*
565     * Set up the scheduler prior starting any interrupts (such as the
566     * timer interrupt). Full topology setup happens at smp_init()
567     * time - but meanwhile we still have a functioning scheduler.
568     */
569    sched_init();
570    /*
571     * Disable preemption - early bootup scheduling is extremely
572     * fragile until we cpu_idle() for the first time.
573     */
574    preempt_disable();
575    if (WARN(!irqs_disabled(),
576         "Interrupts were enabled *very* early, fixing it\n"))
577        local_irq_disable();
578    idr_init_cache();
579    rcu_init();
580    context_tracking_init();
581    radix_tree_init();
582    /* init some links before init_ISA_irqs() */
583    early_irq_init();
584    init_IRQ();
585    tick_init();
586    rcu_init_nohz();
587    init_timers();
588    hrtimers_init();
589    softirq_init();
590    timekeeping_init();
591    time_init();
592    sched_clock_postinit();
593    perf_event_init();
594    profile_init();
595    call_function_init();
596    WARN(!irqs_disabled(), "Interrupts were enabled early\n");
597    early_boot_irqs_disabled = false;
598    local_irq_enable();
599
600    kmem_cache_init_late();
601
602    /*
603     * HACK ALERT! This is early. We're enabling the console before
604     * we've done PCI setups etc, and console_init() must be aware of
605     * this. But we do want output early, in case something goes wrong.
606     */
607    console_init();
608    if (panic_later)
609        panic("Too many boot %s vars at `%s'", panic_later,
610              panic_param);
611
612    lockdep_info();
613
614    /*
615     * Need to run this when irqs are enabled, because it wants
616     * to self-test [hard/soft]-irqs on/off lock inversion bugs
617     * too:
618     */
619    locking_selftest();
620
621#ifdef CONFIG_BLK_DEV_INITRD
622    if (initrd_start && !initrd_below_start_ok &&
623        page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) {
624        pr_crit("initrd overwritten (0x%08lx < 0x%08lx) - disabling it.\n",
625            page_to_pfn(virt_to_page((void *)initrd_start)),
626            min_low_pfn);
627        initrd_start = 0;
628    }
629#endif
630    page_cgroup_init();
631    debug_objects_mem_init();
632    kmemleak_init();
633    setup_per_cpu_pageset();
634    numa_policy_init();
635    if (late_time_init)
636        late_time_init();
637    sched_clock_init();
638    calibrate_delay();
639    pidmap_init();
640    anon_vma_init();
641    acpi_early_init();
642#ifdef CONFIG_X86
643    if (efi_enabled(EFI_RUNTIME_SERVICES))
644        efi_enter_virtual_mode();
645#endif
646#ifdef CONFIG_X86_ESPFIX64
647    /* Should be run before the first non-init thread is created */
648    init_espfix_bsp();
649#endif
650    thread_info_cache_init();
651    cred_init();
652    fork_init(totalram_pages);
653    proc_caches_init();
654    buffer_init();
655    key_init();
656    security_init();
657    dbg_late_init();
658    vfs_caches_init(totalram_pages);
659    signals_init();
660    /* rootfs populating might need page-writeback */
661    page_writeback_init();
662    proc_root_init();
663    cgroup_init();
664    cpuset_init();
665    taskstats_init_early();
666    delayacct_init();
667
668    check_bugs();
669
670    sfi_init_late();
671
672    if (efi_enabled(EFI_RUNTIME_SERVICES)) {
673        efi_late_init();
674        efi_free_boot_services();
675    }
676
677    ftrace_init();
678
679    /* Do the rest non-__init'ed, we're now alive */
680    rest_init();
681}
start_kernel代碼

我們的實驗截圖在最後面;

我們規定【】顯示的是所在的文件目錄以及行數,預設是在/init/main.c中,都是在linux里;前面是在init/main.c的行號,後面是函數自己定義所在的目錄及行數。

【502】 char * command_line;  

/*命令行,用來存放bootloader傳遞過來的參數*/

【509】 lockdep_init(); 【kernel/locking/lockdep.c  3975】

/*建立一個哈希表(hash tables),就是一個前後指向的指針結構體數組。 (函數的主要作用是初始化鎖的狀態跟蹤模塊。由於內核大量使用鎖來進行多進程多處理器的同步操作,死鎖就會在代碼不合理的時候出現,但是要定位哪個鎖比較困難,用哈希表可以跟蹤鎖的使用狀態。死鎖情況:一個進程遞歸加鎖同一把鎖;同一把鎖在兩次中斷中加鎖;幾把鎖形成閉環死鎖)*/

【510】set_task_stack_end_magic(&init_task); 【kernel/fork.c  297】

/*init_task即手工創建的PCB,0號進程即最終的idle進程*/

【511】 smp_setup_processor_id();  【473】

/*針對SMP處理器,用於獲取當前CPU的硬體ID,如果不是多核,函數為空 (判斷是否定義了CONFIG_SMP,如果定義了調用read_cpuid_mpidr讀取寄存器CPUID_MPIDR的值,就是當前正在執行初始化的CPU ID,為了在初始化時做個區分,初始化完成後,所有處理器都是平等的,沒有主從)*/

【512】debug_objects_early_init();【lib/debugobjects.c  1007】

/*初始化哈希桶(hash buckets)並將static object和pool object放入poll列表,這樣堆棧就可以完全操作了 (這個函數的主要作用就是對調試對象進行早期的初始化,就是HASH鎖和靜態對象池進行初始化,執行完後,object tracker已經開始完全運作了)*/

【517】boot_init_stack_canary();【arch/x86/include/asm/stackprotector.h  58】

/*初始化堆棧保護的值,防止棧溢出*/

【519】cgroup_init_early();【kernel/cgroup.c  4882】

/*在系統啟動時初始化cgroups,同時初始化需要early_init的子系統 (這個函數作用是控制組(control groups)早期的初始化,控制組就是定義一組進程具有相同資源的占有程度,比如,可以指定一組進程使用CPU為30%,磁碟IO為40%,網路帶寬為50%。目的就是為了把所有進程分配不同的資源)*/

【521】local_irq_disable();【】

/*關閉當前CPU的所有中斷響應,操作CPSR寄存器。對應後面的*/

【522】early_boot_irqs_disabled = true;

/*系統中斷關閉標誌,當early_init完畢後,會恢復中斷設置標誌為false。*/

【528】boot_cpu_init();【463】

/*設置當前引導系統的CPU在物理上存在,在邏輯上可以使用,並且初始化準備好,即激活當前CPU (在多CPU的系統里,內核需要管理多個CPU,那麼就需要知道系統有多少個CPU,在內核里使用cpu_present_map點陣圖表達有多少個CPU,每一位表示一個CPU的存在。如果是單個CPU,就是第0位設置為1。雖然系統里有多個CPU存在,但是每個CPU不一定可以使用,或者沒有初始化,在內核使用cpu_online_map點陣圖來表示那些CPU可以運行內核代碼和接受中斷處理。隨著移動系統的節能需求,需要對CPU進行節能處理,比如有多個CPU運行時可以提高性能,但花費太多電能,導致電池不耐用,需要減少運行的CPU個數,或者只需要一個CPU運行。這樣內核又引入了一個cpu_possible_map點陣圖,表示最多可以使用多少個CPU。在本函數里就是依次設置這三個點陣圖的標誌,讓引導的CPU物理上存在,已經初始化好,最少需要運行的CPU。)*/

 【529】page_address_init();【mm/highmem.c  478】

 /*初始化高端記憶體的映射表 (在這裡引入了高端記憶體的概念,那麼什麼叫做高端記憶體呢?為什麼要使用高端記憶體呢?其實高端記憶體是相對於低端記憶體而存在的,那麼先要理解一下低端記憶體了。在32位的系統里,最多能訪問的總記憶體是4G,其中3G空間給應用程式,而內核只占用1G的空間。因此,內核能映射的記憶體空間,只有1G大小,但實際上比這個還要小一些,大概是896M,另外128M空間是用來映射高端記憶體使用的。因此0到896M的記憶體空間,就叫做低端記憶體,而高於896M的記憶體,就叫高端記憶體了。如果系統是64位系統,當然就沒未必要有高端記憶體存在了,因為64位有足夠多的地址空間給內核使用,訪問的記憶體可以達到10G都沒有問題。在32位系統里,內核為了訪問超過1G的物理記憶體空間,需要使用高端記憶體映射表。比如當內核需要讀取1G的緩存數據時,就需要分配高端記憶體來使用,這樣才可以管理起來。使用高端記憶體之後,32位的系統也可以訪問達到64G記憶體。在移動操作系統里,目前還沒有這個必要,最多才1G多記憶體)*/

【530】pr_notice("%s", linux_banner);【include/linux/printk.h  244】

/*輸出各種信息(Linux_banner是在kernel/init/version.c中定義的,這個字元串是編譯腳本自動生成的)*/

【530】setup_arch(&command_line);【arch/x86/kernel/setup.c  857】

/*很重要的一個函數arch/arm/kernel/setup.c 
(內核架構相關初始化函數,是非常重要的一個初始化步驟。其中包含了處理器相關參數的初始化、內核啟動參數(tagged list)的獲取和前期處理、記憶體子系統的早期初始化(bootmem分配器))*/

【532】mm_init_cpumask(&init_mm);【/include/linux/mm_types.h  459】

/*每一個任務都有一個mm_struct結構來管理記憶體空間,init_mm是內核的mm_struct*/

【533】setup_command_line(command_line);【371】

/*對cmdline進行備份和保存*/

【534】setup_nr_cpu_ids();【kernel/smp.c  538】

/*設置最多有多少個nr_cpu_ids結構*/

【535】setup_per_cpu_areas();【arch/x86/kernel/setup_percpu.c  167】

/*為系統中每個CPU的per_cpu變數申請空間,同時拷貝初始化段里數據(.data.percpu)*/

【536】smp_prepare_boot_cpu();【arch/x86/include/asm/smp.h  102】

/*為SMP系統里引導CPU(boot-cpu)進行準備工作。在ARM系統單核里是空函數*/

【538】build_all_zonelists(NULL, NULL);【mm/page_alloc.c  3865】

/*設置記憶體管理相關的node(節點,每個CPU一個記憶體節點)和其中的zone(記憶體域,包含於節點中,如)數據結構,以完成記憶體管理子系統的初始化,並設置bootmem分配器*/

【539】page_alloc_init();【mm/page_alloc.c  5567】

/*設置記憶體頁分配通知器*/

【541】pr_notice("Kernel command line: %s\n", boot_command_line);【】見前面

【542】parse_early_param();【445】

/*解析cmdline中的啟動參數*/

【543】after_dashes = parse_args("Booting kernel",static_command_line, __start___param,__stop___param - __start___param,-1, -1, &unknown_bootoption);【kernel/params.c  191】

/*這行代碼主要對傳入內核參數進行解釋,如果不能識別的命令就調用最後參數的函數*/

【551】jump_label_init();【include/linux/jump_label.h  146】

【557】setup_log_buf(0);【kernel/printk/printk.c  887】

/*使用bootmeme分配一個記錄啟動信息的緩衝區*/

【558】pidhash_init();【kernel/pid.c  572】

/*進程ID的HASH表初始化,用bootmem分配並初始化PID散列表,由PID分配器管理空閑和已指派的PID,這樣可以提供通PID進行高效訪問進程結構的信息。LINUX里共有四種類型的PID,因此就有四種HASH表相對應。*/

【559】vfs_caches_init_early();【fs/dcache.c  3410】

/*前期虛擬文件系統(vfs)的緩存初始化*/

【560】sort_main_extable();【kernel/extable.c   42】

/*對內核異常表(exception table)按照異常向量號大小進行排序,以便加速訪問*/

【561】trap_init();【arch/x86/kernel/traps.c  792】

/*對內核陷阱異常進行初始化,在ARM系統里是空函數,沒有任何的初始化*/

【562】mm_init();【486】

/*標記哪些記憶體可以使用,並且告訴系統有多少記憶體可以使用,當然是除了內核使用的記憶體以外 
(初始化內核記憶體分配器,包括六個子函數 
1、page_cgroup_init_flatmem();獲取page_cgroup所需記憶體 
2、mem_init;關閉並釋放bootmem分配器,列印記憶體信息,內核啟動時看到Virtual kernel memory layout:的信息就是這個函數的 

3、kmem_cache_init();初始化slab分配器 
4、percpu_init_late();PerCPU變數系統後期初始化 
5、pgtable_cache_init();也表緩存初始化,arm中是個空函數 6、vmalloc_init();初始化虛擬記憶體分配器*/

【569】sched_init();【kernel/sched/core.c  6998】

/*對進程調度器的數據結構進行初始化,創建運行隊列,設置當前任務的空線程,當前任務的調度策略為CFS調度器 */

【574】preempt_disable();【】

/*關閉優先順序調度。由於每個進程任務都有優先順序,目前系統還沒有完全初始化,還不能打開優先順序調度。*/

【575】if (WARN(!irqs_disabled(),"Interrupts were enabled *very* early, fixing it\n"))  {local_irq_disable();}【】

/*這段代碼主要判斷是否過早打開中斷,如果是這樣,就會提示,並把中斷關閉*/

【578】idr_init_cache();【lib/idr.c  826】

/*為IDR機制分配緩存,主要是為 structidr_layer結構體分配空間*/

【579】rcu_init();【kernel/rcu/tree.c  3749】

/*初始化直接讀拷貝更新的鎖機制。 Read-Copy Update (RCU主要提供在讀取數據機會比較多,但更新比較的少的場合,這樣減少讀取數據鎖的性能低下的問題。)*/

【580】context_tracking_init();【kernel/context_tracking.c  169】

【581】radix_tree_init();【lib/radix-tree.c  1480】

/*內核radis 樹演算法初始化*/

【583】early_irq_init();【kernel/irq/irqdesc.c  230】

/*前期外部中斷描述符初始化,主要初始化數據結構*/

【584】init_IRQ();【arch/x86/kernel/irqinit.c  84】

/*對應架構特定的中斷初始化函數,在ARM中就是machine_desc->init_irq(),就是運行設備描述結構體中的init_irq函數[arch/arm/mach-msm/board-xxx.c]*/

【585】tick_init();【kernel/time/tick-common.c   400】

/*初始化內核時鐘系統,tick control,調用clockevents_register_notifier,就是監聽時鐘變化事件 (這個函數主要作用是初始化時鐘事件管理器的回調函數,比如當時鐘設備添加時處理。在內核里定義了時鐘事件管理器,主要用來管理所有需要周期性地執行任務的設備)*/

【586】rcu_init_nohz();【】

【587】init_timers();【kernel/time/timer.c   1671】

/*初始化引導CPU的時鐘相關的數據結構,註冊時鐘的回調函數,當時鐘到達時可以回調時鐘處理函數,最後初始化時鐘軟體中斷處理*/

【588】hrtimers_init();【kernel/time/hrtimer.c  1742】

/*初始化高精度的定時器,並設置回調函數。*/

【589】softirq_init();【/kernel/softirq.c  630】

/*初始化軟體中斷,軟體中斷與硬體中斷區別就是中斷發生時,軟體中斷是使用線程來監視中斷信號,而硬體中斷是使用CPU硬體來監視中斷。*/

【590】timekeeping_init();【kernel/time/timekeeping.c  993】

/*初始化系統時鐘計時,並且初始化內核里與時鐘計時相關的變數。*/

【591】time_init();【arch/x86/kernel/time.c   94】

/*初始化系統時鐘。開啟一個硬體定時器,開始產生系統時鐘就是system_timer的初始化,arch/arm/mach-msm/board-*.c */

【592】sched_clock_postinit();【kernel/time/sched_clock.c   172】

【593】perf_event_init();【kernel/events/core.c   8208】

/*CPU性能監視機制初始化,此機制包括CPU同一時間執行指令數,cache miss數,分支預測失敗次數等性能參數*/

【594】profile_init();【/kernel/profile.c   99】

/*分配內核性能統計保存的記憶體,以便統計的性能變數可以保存到這裡*/

【595】call_function_init();【kernel/smp.c   89】

/*初始化所有CPU的call_single_queue,同時註冊CPU熱插拔通知函數到CPU通知鏈中*/

【596】WARN(!irqs_disabled(), "Interrupts were enabled early\n");   early_boot_irqs_disabled = false;   local_irq_enable();【】

/*對應前面的local_irq_disable() (打開本CPU的中斷,也即允許本CPU處理中斷事件,在這裡打開引CPU的中斷處理。如果有多核心,別的CPU還沒有打開中斷處理。)*/

【600】kmem_cache_init_late();【/mm/slub.c   3612】

/*這是內核記憶體緩存(slab分配器)的後期初始化,當初始化完成之後,就可以使用通用記憶體緩存了*/

【607】console_init();【drivers/tty/tty_io.c   3510】

/*初始化控制台,從這個函數之後就可以輸出內容到控制台了。在這個函數初化之前,都沒有辦法輸出內容,就是輸出,也是寫到輸出緩衝區里,緩存起來,等到這個函數調用之後,就立即輸出內容*/

【608】if (panic_later)  panic("Too many boot %s vars at `%s'", panic_later,panic_param);【】

/*判斷分析輸入的參數是否出錯,如果有出錯,就啟動控制台輸出之後,立即列印出錯的參數,以便用戶立即看到出錯的地方。*/

【612】lockdep_info();【kernel/locking/lockdep.c   3997】

/*列印鎖的依賴信息,用來調試鎖。通過這個函數可以查看目前鎖的狀態,以便可以發現那些鎖產生死鎖,那些鎖使用有問題。*/

【619】locking_selftest();【lib/locking-selftest.c   1795】

/*測試鎖的API是否使用正常,進行自我測試。比如測試自旋鎖、讀寫鎖、一般信號量和讀寫信號量。*/

【621】

#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【】

/*檢查initrd的位置是否符合要求,也就是判斷傳遞進來initrd_start對應的物理地址是否正常,如果有誤就列印錯誤信息,並清零initrd_start。*/

【630】page_cgroup_init();【mm/page_cgroup.c   271】

/*初始化容器組的頁面記憶體分配,mem_cgroup是cgroup體系中提供的用於memory隔離的功能,*/

【631】debug_objects_mem_init();【lib/debugobjects.c  1081】

/*這個函數是創建調試對象記憶體分配初始化,所以緊跟記憶體緩存初始化後面*/

【632】kmemleak_init();【mm/kmemleak.c   1807】

/*內核記憶體泄漏檢測機制初始化;*/

【633】setup_per_cpu_pageset();【mm/page_alloc.c   4309】

/*創建每個CPU的高速緩存集合數組並初始化,此前只有啟動頁組。因為每個CPU都不定時需要使用一些頁面記憶體和釋放頁面記憶體,為了提高效率,就預先創建一些記憶體頁面作為每個CPU的頁面集合。*/

【634】numa_policy_init();【mm/mempolicy.c   2587】

/*初始化NUMA的記憶體訪問策略。所謂NUMA,它是NonUniform Memory AccessAchitecture(非一致性記憶體訪問)的縮寫,主要用來提高多個CPU訪問記憶體的速度。因為多個CPU訪問同一個節點的記憶體速度遠遠比訪問多個節點的速度來得快。*/

【635】if (late_time_init) late_time_init();【121】

/*主要運行時鐘相關後期的初始化功能。*/

【637】sched_clock_init();【kernel/sched/clock.c   145】

/*對每個CPU進行系統進程調度時鐘初始化*/

【638】calibrate_delay();【init/calibrate.c   274】

/*主要計算CPU需要校準的時間,這裡說的時間是CPU執行時間。如果是引導CPU,這個函數計算出來的校準時間是不需要使用的,主要使用在非引導CPU上,因為非引導CPU執行的頻率不一樣,導致時間計算不准確。BogoMIPS值,也是衡量cpu性能的標誌*/

【639】pidmap_init();【/kernel/pid.c   586】

/*進程點陣圖初始化,一般情況下使用一頁來表示所有進程占用情況。*/

【640】anon_vma_init();【mm/rmap.c   376】

/*初始化反向映射的匿名記憶體,提供反向查找記憶體的結構指針位置,快速地回收記憶體。*/

【641】acpi_early_init();【/drivers/acpi/bus.c   470】

/*這個函數是初始化ACPI電源管理。高級配置及電源介面(Advanced Configuration and Power Interface)ACPI規範介紹ACPI能使軟、硬體、操作系統(OS),主機板和外圍設備,依照一定的方式管理用電情況,系統硬體產生的Hot-Plug事件,讓操作系統從用戶的角度上直接支配即插即用設備,不同於以往直接通過基於BIOS 的方式的管理。*/

【642】

#ifdef CONFIG_X86
 if (efi_enabled(EFI_RUNTIME_SERVICES))
  efi_enter_virtual_mode();
#endif【】

/*初始化EFI的介面,併進入虛擬模式。EFI是ExtensibleFirmware Interface的縮寫,就是INTEL公司新開發的BIOS介面。*/

【650】thread_info_cache_init();【478】

/*線程信息(thread_info)的緩存初始化。*/

【651】cred_init();【/kernel/cred.c   561】

/*任務信用系統初始化 */

【652】fork_init(totaltam_pages)【kernel/fork.c   652】

/*根據當前物理記憶體計算出來可以創建進程(線程)的最大數量,併進行進程環境初始化,為task_struct分配空間。*/

【653】proc_caches_init();【kernel/fork.c   1762】

/*進程緩存初始化,為進程初始化創建機制所需的其他數據結構申請空間*/

【654】buffer_init();【fs/buffer.c   3413】

/*初始化文件系統的緩衝區,並計算最大可以使用的文件緩存。*/

【655】key_init();【security/keys/key.c   1123】

/*初始化內核安全鍵管理列表和結構,內核密鑰管理系統*/

【656】security_init();【security/security.c   65】

/*初始化內核安全管理框架,以便提供訪問文件/登錄等許可權。*/

【657】dbg_late_init();【kernel/debug/debug_core.c   839】

/*內核調試系統後期初始化 */

【658】vfs_caches_init(totalram_pages);【/fs/dcache.c   3416】

/*虛擬文件系統進行緩存初始化,提高虛擬文件系統的訪問速度*/

【659】signals_init();【kernel/signal.c  3623】

/*初始化信號隊列緩存。信號管理系統*/

【661】page_writeback_init();【mm/page-writeback.c   1765】

/*頁面寫機制初始化 */

【662】proc_root_init();【fs/proc/root.c   165】

/*初始化系統進程文件系統,主要提供內核與用戶進行交互的平臺,方便用戶實時查看進程的信息。*/

【663】cgroup_init();【kernel/cgroup.c   4916】

/*進程式控制制組正式初始化,主要用來為進程和其子程提供性能控制。比如限定這組進程的CPU使用率為20% */

【664】cpuset_init();【/kernel/cpuset.c   2068】

/*初始化CPUSET,CPUSET主要為控制組提供CPU和記憶體節點的管理的結構。*/

【665】taskstats_init_early();【kernel/taskstats.c   691】

/*任務狀態早期初始化,為結構體獲取高速緩存,並初始化互斥機制。任務狀態主要向用戶提供任務的狀態信息。*/

【666】delayacct_init();【kernel/delayacct.c   35】

/*任務延遲機制初始化,初始化每個任務延時計數。當一個任務等CPU運行,或者等IO同步時,都需要計算等待時間。*/

【668】check_bugs();【arch/x86/kernel/cpu/bugs.c   66】

/*檢查CPU配置、FPU等是否非法使用不具備的功能,檢查CPU BUG,軟體規避BUG*/

【670】sfi_init_late();【drivers/sfi/sfi_core.c   500】

/*SFI 初始程式晚期設置函數*/

【677】ftrace_init();【kernel/trace/ftrace.c   4697】

/*功能跟蹤調試機制初始化,初始化內核跟蹤模塊,ftrace的作用是幫助開發人員瞭解Linux 內核的運行時行為,以便進行故障調試或性能分析 function trace.*/

【680】rest_init();【393】

/*剩餘的初始化,至此,內核已經開始工作了*/

 

 

 

 

 

 

 

 

 

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...