Linux内核完成大量内存/调度/时间子系统初始化的关键阶段

printk: legacy bootconsole [sbi0] disabled是 console_init()→ register_console()里反注册 early console 时打的,它发生在 start_kernel()中 console_init()返回之后、调用 calibrate_delay()(即 "Calibrating delay loop...")之前。这段区间是内核完成大量内存/调度/时间子系统初始化的关键阶段。

以 Linux 5.x/6.x init/main.c::start_kernel()为主,流程如下:


console_init()之后 → calibrate_delay()之前的调用链

复制代码
start_kernel()
{
    ...
    console_init();          // ← 这里 sbi0 bootconsole 被 disable,正式 console 注册
                               //   打印: "console [ttyS0] enabled"
                               //         "legacy bootconsole [sbi0] disabled"

    if (panic_later) panic(...);

    lockdep_info();           // 打印 lockdep 信息(若 CONFIG_LOCKDEP=y)
    locking_selftest();        // 锁依赖自测(rwlock/mutex/ww_mutex 等)

    page_ext_init();           // 页扩展调试初始化(DEBUG_PAGEALLOC/KASAN 场景)
    debug_objects_mem_init();  // debugobjects 内存池
    kmemleak_init();           // 内存泄漏检测初始化

    setup_per_cpu_pageset();   // 每个 CPU 的页集(pcp)初始化
    numa_policy_init();        // NUMA 内存策略(UP 上基本空操作)

    if (late_time_init)       // RISC-V 通常在这里调 riscv_time_init()
        late_time_init();

    sched_clock_init();        // 调度器时钟源初始化(sched_clock 可用)
    calibrate_delay();         // ← 打印 "Calibrating delay loop..."
    ...
}

各步骤简要说明

函数 作用
console_init()返回​ bootconsolesbi0 已 unregister,正式串口 console 接管 printk 输出
**lockdep_info()/ locking_selftest()**​ 若开启 LOCKDEP,做锁反转检测自测并打印结果
**debug_objects_mem_init()/ kmemleak_init()**​ 初始化对象生命周期追踪和内存泄漏检测(调试内核可见)
**setup_per_cpu_pageset()**​ 为每个 CPU 建立 struct per_cpu_pageset,zone->pageset 指向它
**numa_policy_init()**​ 初始化 NUMA 默认内存分配策略(非 NUMA 基本是空)
**late_time_init()**​ RISC-V 平台在此完成 clint/clocksource 时间源注册(早于 calibrate_delay 用 timer)
**sched_clock_init()**​ 使能 sched_clock(),部分架构此前不可用
**calibrate_delay()**​ 跑 delay loop 测定 lpj(loops_per_jiffy),打印 **Calibrating delay loop...**​

特别说明(RISC-V SBI 场景)

  • [sbi0] disabled说明 earlycon=sbi的 early console 已被 unregister_console()摘除,正式 8250/SIFIVE/NS16550 串口 console 已接管

  • RISC-V 的 late_time_init = riscv_time_init(在 setup_arch()中赋值),在 calibrate_delay()之前被调用,确保 timer 已就绪------否则 calibrate_delay()可能用 jiffy 方式校准而非高精度 timer

  • 如果 keep_bootcon在 cmdline,bootconsole 不注销,这行日志不会出现


一句话总结: ​ bootconsole [sbi0] disabled是 console_init()退出的标志,之后内核依次做完 lockdep 自检 → debug/kmemleak → per-cpu pageset → NUMA policy → late_time_init(RISC-V timer) → sched_clock_init,然后立刻进 calibrate_delay()打出 "Calibrating delay loop"。

相关推荐
前端双越老师8 小时前
程序员 1v1 访谈系列第十一期:应届生别做开发
java·agent·ai编程
Captain1314_李祖团8 小时前
5. MLIR相关语法
java·前端·javascript
Blockbuater_drug8 小时前
OpenMM分子动力学模拟02 安装:Linux:conda 一条命令装通 GPU 加速的分子模拟环境
linux·conda·cuda·gpu驱动·pythonpath·openmm安装
Rain的Java大神之路8 小时前
面试官让你把 LLM、RAG、Agent、MCP 串起来讲清楚,90% 的 Java 工程师当场露馅
java·后端·面试
程序员JerrySUN8 小时前
PCIe Gen5 SSD 为什么读得快、写得慢?从存储原理到 Linux 性能实测
linux·服务器·网络
Android系统攻城狮8 小时前
Linux FFmpeg深度解析之avcodec_parameters_copy调用流程与实战(二十五)
linux·运维·服务器·ffmpeg·音视频·车载音频
无所谓^_^8 小时前
个人健康管理系统 | Springboot3 | Vue3
java·vue·毕业设计·springboot·课程设计·毕设·前后端分离
恋猫de小郭8 小时前
Flutter 可以更直接地调用原生 API 了,Dart Direct Native Interop
android·前端·flutter
杨凯凡8 小时前
Spring Boot 的 @Transactional 为什么会失效?从代理、自调用到异常回滚的排查实战
java·spring boot·spring·事务·后端开发
Data analyse4568 小时前
web-vitals库接入:LCP、INP、CLS上报与阈值
前端·javascript·数据分析