
板子上电后黑屏、initramfs挂不上根、换内核后进不了系统问题多半卡在早期启动链而不是业务驱动本身。本文沿start_kernel→rest_init→kernel_init→run_init_process把主路径走通便于对照dmesg/initcall_debug定位卡点。源码锚点路径作用init/main.cstart_kernel、rest_init、kernel_init、do_basic_setupinit/main.cdo_initcalls按 level 执行__initcall段arch/*/kernel/setup.csetup_arch解析 cmdline、early mem、DT/ACPIinclude/linux/init.hearly_initcall/core_initcall/device_initcall等宏Documentation/admin-guide/kernel-parameters.txt启动参数约定Documentation/admin-guide/initrd.rstinitramfs / initrd 行为核心入口概念摘录以你树中init/main.c为准/* init/main.c — 启动主路径骨架 */asmlinkage __visiblevoid__initstart_kernel(void){/* setup_arch → mm_init → sched_init → … → rest_init() 创建 kernel_init / kthreadd */}staticint__refkernel_init(void*unused){/* wait_for_completion(kthreadd_done); kernel_init_freeable() → do_basic_setup() → do_initcalls → prepare_namespace / run_init_process */}initcall 等级include/linux/init.h/* 由早到晚示意 */early_initcall/pure_initcall/core_initcall/postcore_initcall/arch_initcall/subsys_initcall/fs_initcall/device_initcall/late_initcall调用链固件/Bootloader 跳转内核入口arch 相关 head.S / EFI stub → start_kernel() /* init/main.c */ → setup_arch(command_line) /* 解析 cmdline、memblock、DT/ACPI */ → mm_init / sched_init / … /* 内存、调度等基础子系统 */ → rest_init() → kernel_thread(kernel_init, …) → kernel_thread(kthreadd, …) → cpu_startup_entry() /* idle */ kernel_init → kernel_init_freeable() → do_basic_setup() → do_initcalls() /* 按 level 调各 __init 函数 */ → 挂载根 / 准备用户态 → run_init_process(/sbin/init 等候选) → 用户态 PID 1 接管cmdline 与早期用户态Bootloader 传入 boot_command_line → parse_args / 各 __setup 回调 initramfs若启用 → 解压到 rootfs → 在真实根就绪前提供驱动与工具 → pivot_root / switch_root用户态脚本→ 真实根上的 init重点知识1.start_kernel只做「能跑调度与中断」的最小集在创建kernel_init之前架构相关初始化、内存、调度、IRQ 等必须就绪。卡在极早阶段时printk可能还不可见需要earlyprintk/earlycon而不是只看后期dmesg。2. initcall 顺序决定驱动能否在挂根前就绪块设备、virtio、文件系统等若放错 level 或依赖未满足会出现「内核起来了但找不到根」。排障首选initcall_debug对照卡在哪个符号。3. cmdline 是启动策略开关不是装饰root、rootwait、init、rdinit、console直接影响能否进用户态。生产环境遗留acpioff/nomodeset会造成隐性性能或设备枚举问题。4. initramfs 与模块目录必须跟内核版本对齐uname-rls/lib/modules/$(uname-r)/# 升级内核后重建发行版示例sudoupdate-initramfs-u-k$(uname-r)# Debian/Ubuntu# 或dracut --force缺virtio_blk/mmc/nvme等根设备驱动时典型日志是 root mount failed而不是业务服务挂掉。5. 设计意图与踩坑意图把「硬件无关的通用启动」集中在start_kernel把设备探测推迟到 initcall再用 initramfs 填早期依赖。坑只换vmlinuz不重建 initramfs。坑init/bin/bash排障参数留在 GRUB 永久配置。坑模块 vermagic 与运行中内核不一致 →Invalid module format。坑串口未配console现场只能「黑屏」无法收早期日志。Checklist能指出start_kernel/kernel_init/do_initcalls所在文件并口述主链用initcall_debug能定位卡在哪个 initcall 符号uname -r与/lib/modules/$(uname -r)、initramfs 三者一致GRUB/cmdline 中root/console与板级实际设备节点匹配根设备相关驱动在 initramfs 内或编进内核换内核后已重建排障临时参数init、single未污染生产 cmdline