61. Linux內核啟動流程簡介

一、vmlinux.lds簡介

從arch/arm/kernel/vmlinux.lds分析Linux內核第一行啟動代碼。找到

ENTRY(stext)
入口函數是stext,image和zImage是經過壓縮的,Linux內核會先進行解壓縮,解壓縮完成以后就要運行Linux內核。要求:
1、MMU關閉
2、D cache關閉
3、I cache無所謂
4、r0 = 0。
5、r1 = machine nr
6、r2=atags 或設備樹

二、Linux入口stext

__vet_atags 函數驗證atags或dtb是否有效,如果使用設備樹的話就是dtb。
__create_page_tables 創建頁表。
ldr	r13, =__mmap_switched 也就是r13保存__mmap_switched。
__enable_mmu  使能MMU-> __turn_mmu_on->_mmap_switched->start_kernel  啟動內核。
Linux內核第一階段。

三、__mmap_switched函數

四、start_kernel函數

Linux內核第二階段

/linux/linux-imx-rel_imx_4.1.15_2.1.0_ga/init/main.c

asmlinkage __visible void __init start_kernel(void)
{char *command_line;char *after_dashes;/** Need to run as early as possible, to initialize the* lockdep hash:*/lockdep_init();set_task_stack_end_magic(&init_task);smp_setup_processor_id();debug_objects_early_init();/** Set up the the initial canary ASAP:*/boot_init_stack_canary();cgroup_init_early();local_irq_disable();early_boot_irqs_disabled = true;/** Interrupts are still disabled. Do necessary setups, then* enable them*/boot_cpu_init();page_address_init();pr_notice("%s", linux_banner);setup_arch(&command_line);mm_init_cpumask(&init_mm);setup_command_line(command_line);setup_nr_cpu_ids();setup_per_cpu_areas();smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */build_all_zonelists(NULL, NULL);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, &unknown_bootoption);if (!IS_ERR_OR_NULL(after_dashes))parse_args("Setting init args", after_dashes, NULL, 0, -1, -1,set_init_arg);jump_label_init();/** These use large bootmem allocations and must precede* kmem_cache_init()*/setup_log_buf(0);pidhash_init();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();idr_init_cache();rcu_init();/* trace_printk() and trace points may be used after this */trace_init();context_tracking_init();radix_tree_init();/* init some links before init_ISA_irqs() */early_irq_init();init_IRQ();tick_init();rcu_init_nohz();init_timers();hrtimers_init();softirq_init();timekeeping_init();time_init();sched_clock_postinit();perf_event_init();profile_init();call_function_init();WARN(!irqs_disabled(), "Interrupts were enabled early\n");early_boot_irqs_disabled = false;local_irq_enable();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_INITRDif (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;}
#endifpage_ext_init();debug_objects_mem_init();kmemleak_init();setup_per_cpu_pageset();numa_policy_init();if (late_time_init)late_time_init();sched_clock_init();calibrate_delay();pidmap_init();anon_vma_init();acpi_early_init();
#ifdef CONFIG_X86if (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();
#endifthread_info_cache_init();cred_init();fork_init();proc_caches_init();buffer_init();key_init();security_init();dbg_late_init();vfs_caches_init(totalram_pages);signals_init();/* rootfs populating might need page-writeback */page_writeback_init();proc_root_init();nsfs_init();cpuset_init();cgroup_init();taskstats_init_early();delayacct_init();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 */rest_init();
}
start_kernel-> rest_init-> kernel_thread(kernel_init, NULL, CLONE_FS);  創建kernel_init進程。也就是
init進程,PID=1-> kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);  創建kthreadd
進程,進程PID為2。-> cpu_startup_entry 進入空閑進程,也就是主進程退化為空閑進程,idle。
啟動開發板,輸入:ps -A,列出當前系統所有進程。

五、reset_init函數

/linux/linux-imx-rel_imx_4.1.15_2.1.0_ga/init/main.c

static noinline void __init_refok rest_init(void)
{int pid;rcu_scheduler_starting();smpboot_thread_init();/** We need to spawn init first so that it obtains pid 1, however* the init task will end up wanting to create kthreads, which, if* we schedule it before we create kthreadd, will OOPS.*/kernel_thread(kernel_init, NULL, CLONE_FS);numa_default_policy();pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);rcu_read_lock();kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);rcu_read_unlock();complete(&kthreadd_done);/** The boot idle thread must execute schedule()* at least once to get things moving:*/init_idle_bootup_task(current);schedule_preempt_disabled();/* Call into cpu_idle with preempt disabled */cpu_startup_entry(CPUHP_ONLINE);
}

六、init進程

	kernel_init -> kernel_init_freeable-> 設置標準輸入、標準輸出、標準錯誤使用console,比如ttymxc0-> ramdisk_execute_command = "/init";-> 檢查/init是否存在,存在的話就運行。-> uboot傳遞給Linux內核的bootargs可以自定init=xxx,或者叫命令行參數。 
有一些開發板會設置init=linuxrc。-> 試著運行/sbin/init。-> /etc/init-> /bin/init-> /bin/sh
可以看出,最終引出根文件系統。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/894882.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/894882.shtml
英文地址,請注明出處:http://en.pswp.cn/news/894882.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

汽車智能座艙的技術演進與用戶體驗重構 —— 基于多模態交互與 AI 融合的范式創新

摘要&#xff1a; 汽車智能座艙作為人 - 車 - 環境交互的核心載體&#xff0c;正經歷從功能驅動到體驗驅動的范式變革。本文通過技術解構與用戶行為分析&#xff0c;深入揭示智能座艙在異構計算、多模態感知、服務生態等維度的創新路徑。研究表明&#xff0c;智能座艙的競爭焦…

使用 Let‘s Encrypt 和 OpenResty 實現域名轉發與 SSL 配置

在搭建網站或服務時&#xff0c;確保域名的安全性和正確的流量轉發是非常重要的。本文將介紹如何使用 Let’s Encrypt 獲取免費的 SSL 證書&#xff0c;并將其配置到 OpenResty 中&#xff0c;同時實現特定的域名轉發規則。這不僅可以提升網站的安全性&#xff0c;還能優化流量…

SpringBoot3整合Swagger3時出現Type javax.servlet.http.HttpServletRequest not present錯誤

目錄 錯誤詳情 錯誤原因 解決方法 引入依賴 修改配置信息 創建文件 訪問 錯誤詳情 錯誤原因 SpringBoot3和Swagger3版本不匹配 解決方法 使用springdoc替代springfox&#xff0c;具體步驟如下&#xff1a; 引入依賴 在pom.xml文件中添加如下依賴&#xff1a; <…

ChatGPT提問技巧:行業熱門應用提示詞案例-文案寫作

ChatGPT 作為強大的 AI 語言模型&#xff0c;已經成為文案寫作的得力助手。但要讓它寫出真正符合你需求的文案&#xff0c;關鍵在于如何與它“溝通”&#xff0c;也就是如何設計提示詞&#xff08;Prompt&#xff09;。以下是一些實用的提示詞案例&#xff0c;幫助你解鎖 ChatG…

供排水水工公司開展企業獲得用水營商環境滿意度調查

為了持續提升企業的供水服務品質&#xff0c;進一步優化當地的營商環境&#xff0c;深圳市供排水公司水工公司緊密結合其實際工作情況&#xff0c;特別委托民安智庫開展了2023年度優化營商環境調查專項工作。該項目的核心目的是深入了解并評估市各類獲得用水企業的用水環境滿意…

【Elasticsearch】分桶聚合功能概述

這些聚合功能可以根據它們的作用和應用場景分為幾大類&#xff0c;以下是分類后的結果&#xff1a; 1.基礎聚合&#xff08;Basic Aggregations&#xff09; ? Terms&#xff08;字段聚合&#xff09; 根據字段值對數據進行分組并統計。 例子&#xff1a;按產品類別統計銷…

mysql的cpu使用率100%問題排查

背景 線上mysql服務器經常性出現cpu使用率100%的告警&#xff0c; 因此整理一下排查該問題的常規流程。 1. 確認CPU占用來源 檢查系統進程 使用 top 或 htop 命令&#xff0c;確認是否是 mysqld 進程導致CPU滿載&#xff1a;top -c -p $(pgrep mysqld)2. 實時分析MySQL活動 …

人工智能賦能企業系統架構設計:以ERP與CRM系統為例

一、引言 1.1 研究背景與意義 在數字化時代&#xff0c;信息技術飛速發展&#xff0c;人工智能&#xff08;Artificial Intelligence, AI&#xff09;作為一項具有變革性的技術&#xff0c;正深刻地影響著各個領域。近年來&#xff0c;AI 在技術上取得了顯著突破&#xff0c;…

使用jmeter進行壓力測試

使用jmeter進行壓力測試 jmeter安裝 官網安裝包下載&#xff0c;選擇二進制文件&#xff0c;解壓。 tar -xzvf apache-jmeter-x.tgz依賴jdk安裝。 yum install java-1.8.0-openjdk環境變量配置&#xff0c;修改/etc/profile文件&#xff0c;添加以下內容。 export JMETER/…

深入理解流(Streams)—— 聲明式數據處理的藝術

1. 引言 大家好&#xff01;歡迎來到本系列博客的第三篇。在前兩篇文章中&#xff0c;我們已經領略了 Java 8 中 行為參數化 和 Lambda 表達式 的魅力。 在第 1 章 Java行為參數化&#xff1a;從啰嗦到簡潔的代碼進化中&#xff0c;我們了解到如何通過將行為&#xff08;代碼…

【Linux】之【Get√】nmcli device wifi list 與 wpa_cli scan 和 wpa_cli scan_result 區別

nmcli device wifi list 是 NetworkManager 的命令行工具 nmcli 的一部分&#xff0c;它用于列出當前可用的無線網絡。它的作用和 wpa_cli 的掃描功能類似&#xff0c;但有一些不同點。 1. nmcli device wifi list 功能&#xff1a; nmcli device wifi list 命令用于顯示當前…

【藍橋杯嵌入式】6_定時器輸入捕獲

全部代碼網盤自取 鏈接&#xff1a;https://pan.baidu.com/s/1PX2NCQxnADxYBQx5CsOgPA?pwd3ii2 提取碼&#xff1a;3ii2 這是兩個信號發生器&#xff0c;可以通過調節板上的兩個電位器R39和R40調節輸出頻率。 將PB4、PA15選擇ch1&#xff0c;兩個信號發生器只能選擇TIM3和TIM…

詳解SQLAlchemy的函數relationship

在 SQLAlchemy 中&#xff0c;relationship 是一個非常重要的函數&#xff0c;用于定義模型之間的關系。它用于在 ORM 層面上表示數據庫表之間的關聯關系&#xff08;如 1 對 1、1 對多和多對多&#xff09;。relationship 的主要作用是提供一個高級接口&#xff0c;用于在模型…

分桶函數的使用

除了 NTILE 函數&#xff0c;SQL 中還有其他一些與 分桶&#xff08;bucketization&#xff09;相關的函數&#xff0c;雖然它們的實現方式不同&#xff0c;但都涉及將數據分成多個區間或組。以下是一些常用的分桶函數&#xff1a; 1. CASE 語句 雖然 CASE 不是開窗函數&…

iOS 音頻錄制、播放與格式轉換

iOS 音頻錄制、播放與格式轉換:基于 AVFoundation 和 FFmpegKit 的實現 在 iOS 開發中,音頻處理是一個非常常見的需求,比如錄音、播放音頻、音頻格式轉換等。本文將詳細解讀一段基于 AVFoundation 和 FFmpegKit 的代碼,展示如何實現音頻錄制、播放以及 PCM 和 AAC 格式之間…

數據結構與算法(test1)

一、樹和二叉樹 1. 看圖&#xff0c;完成以下填空 (1).樹的度為________。 (2).樹中結點的最大層次&#xff0c;稱為樹的_____或樹的______&#xff0c;值是______。 (3).結點A和B的度分別為________ 和 ________。 (4).結點A是結點B的________。 (5).結點B是結點A的________…

新版AndroidStudio 修改 jdk版本

一、問題 之前&#xff0c;在安卓項目中配置JDK和Gradle的過程非常直觀&#xff0c;只需要進入Android Studio的File菜單中的Project Structure即可進行設置&#xff0c;十分方便。 如下圖可以在這修改JDK: 但是升級AndroidStudio之后&#xff0c;比如我升級到了Android Stu…

litemall,又一個小商場系統

litemall Spring Boot后端 Vue管理員前端 微信小程序用戶前端 Vue用戶移動端 代碼地址&#xff1a;litemall: 又一個小商城。 litemall Spring Boot后端 Vue管理員前端 微信小程序用戶前端 Vue用戶移動端

cursor 開發java項目教程簡單上手

1.官網下載 Cursor - The AI Code Editor 下載完后注冊賬號&#xff0c;可以使用無限郵的方式 注冊完之后 設置中文 可以選擇設置為中文 Ctrl Shift X 進入設置頁面輸入chinese 然后重啟 更改jdk跟maven倉庫設置 ctrlshiftp 打開輸入框后輸入json&#xff0c;把下面代碼…

安裝和使用 Ollama(實驗環境windows)

下載安裝 下載 https://ollama.com/download/windows 安裝 Windows 安裝 如果直接雙擊 OllamaSetup.exe 安裝&#xff0c;默認會安裝到 C 盤&#xff0c;如果需要指定安裝目錄&#xff0c;需要通過命令行指定安裝地址&#xff0c;如下&#xff1a; # 切換到安裝目錄 C:\Use…