QEMU上无法启动的Tizen Linux内核调试方法求助
针对QEMU上Tizen 4.19.49内核新调度器启动失败的调试方案
1. 校准QEMU启动参数与内核调试配置
- QEMU启动时必须添加调试挂起参数:
qemu-system-x86_64 -kernel arch/x86/boot/bzImage -initrd rootfs.img -s -S -serial stdio,其中-S会让内核启动后立刻暂停,等待gdb连接,避免内核直接崩溃后无法调试;-serial stdio用于输出早期日志。 - 检查内核
.config配置:强制开启CONFIG_DEBUG_KERNEL、CONFIG_DEBUG_INFO(确保gdb能解析符号)、CONFIG_PRINTK、CONFIG_EARLY_PRINTK(启动最早期就能输出日志,普通printk可能还未初始化就崩溃),编译时保留-g编译参数。
2. 逐步隔离调度器代码定位问题
- 先恢复
kernel/sched/core.c的所有修改,仅保留new_scheduler.c的最基础框架(比如只注册调度器,不替换CFS),验证内核能否正常启动。 - 若能启动,再逐步加回
core.c的修改,每修改一处就编译测试,直到定位到导致崩溃的代码段。 - 暂时注释掉将新调度器设为默认的代码,用CFS正常启动系统后,通过
echo new_sched > /sys/kernel/sched_scheduler动态切换调度器,避开启动阶段的崩溃风险。
3. 用Early Printk输出启动早期日志
- 在新调度器的初始化函数、核心入口逻辑的最开头添加
early_printk("new_sched: enter init\n");这类日志,early_printk会绕过常规printk的初始化流程,在启动最早期输出信息,判断崩溃发生在初始化阶段还是调度执行阶段。
4. 修正GDB调试流程
- 启动QEMU后,新开终端执行
gdb vmlinux,输入target remote localhost:1234连接QEMU的调试端口。 - 先设置断点:
b new_sched_init,再执行c让内核继续运行,观察是否能命中断点;若内核崩溃,执行bt查看栈回溯,定位崩溃的调用链。 - 若GDB仍无法执行命令,检查GDB与QEMU的版本兼容性,建议使用GDB 8.0以上版本调试4.19内核。
5. 静态代码检查与临界区校验
- 用
sparse工具检查代码:sparse -Weverything kernel/sched/core.c kernel/sched/new_scheduler.c,找出类型不匹配、未初始化变量、指针非法引用等潜在问题。 - 重点检查调度器代码中的自旋锁操作(
spin_lock/spin_unlock)、链表操作(list_add/list_del),启动阶段的锁机制与运行时存在差异,非法操作极易导致崩溃。
内容的提问来源于stack exchange,提问作者hadonas
相关产品推荐
相关产品推荐

