dump_stack对SMP特性的支持

本文基于5.10.198版本。其实现与当前6.x系列实现有较大差别。

可以看到,在不支持SMP特性的实现上,代码非常简单:

在支持SMP特性的实现上,其代码实现如下。

首先,函数进入屏蔽中断并保存中断屏蔽状态,函数退出前恢复。

原子变量dump_lock在dump_stack没有被调用的时候是-1。在被调用的时候记录当前CPU的ID。

如果dump_stack之前没有被调用,was_locked变量置0。调用栈dump后恢复为-1。

如果在当前CPU上,dump_stack已经被调用了,还没有恢复为-1,允许在当前CPU上再次调用dump_stack。这样输出的信息可能会被截为两段。这种情况应该是前一个调用dump_stack的进程被抢占了。是的,该函数就是这样设计的。代码中的注释特别说明了这一点。

这种情况下was_locked变量置1。

最后一种情况是dump_stack已经在一颗CPU上被调用了,其他CPU在这个时候也调用了这个函数,那就只能等待了。

Run /sbin/init as init process [ 5.018432] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00007f00 [ 7.471518] CPU: 3 PID: 1 Comm: init Not tainted 5.10.209 #85 [ 7.477258] Hardware name: Rockchip RK3588 EVB4 LP4 V10 Board (DT) [ 7.483431] Call trace: [ 7.485891] dump_backtrace+0x0/0x1f0 [ 7.489548] show_stack+0x1c/0x24 [ 7.492863] dump_stack_lvl+0xe0/0x104 [ 7.496611] dump_stack+0x14/0x30 [ 7.499924] panic+0x18c/0x364 [ 7.502978] do_exit+0x94c/0x9d0 [ 7.506204] do_group_exit+0x3c/0xa4 [ 7.509779] __wake_up_parent+0x0/0x30 [ 7.513530] el0_svc_common.constprop.0+0x6c/0x1c0 [ 7.518315] do_el0_svc+0x20/0x30 [ 7.521626] el0_svc+0x1c/0x2c [ 7.524678] el0_sync_handler+0xa8/0xac [ 7.528509] el0_sync+0x158/0x180 [ 7.531824] SMP: stopping secondary CPUs [ 7.535797] CPU0: stopping [ 7.535802] CPU2: stopping [ 7.535805] CPU1: stopping [ 7.535808] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 5.10.209 #85 [ 7.535810] Hardware name: Rockchip RK3588 EVB4 LP4 V10 Board (DT) [ 7.535811] Call trace: [ 7.535816] dump_backtrace+0x0/0x1f0 [ 7.535820] show_stack+0x1c/0x24 [ 7.535823] dump_stack_lvl+0xe0/0x104 [ 7.535826] dump_stack+0x14/0x30 [ 7.535829] local_cpu_stop+0x74/0x7c [ 7.535831] ipi_handler+0x174/0x2a4 [ 7.535836] handle_percpu_devid_fasteoi_ipi+0x80/0x160 [ 7.535842] __handle_domain_irq+0x78/0xe0 [ 7.535844] gic_handle_irq+0xe0/0x2e0 [ 7.535846] el1_irq+0xc8/0x180 [ 7.535852] cpuidle_enter_state+0xc4/0x404 [ 7.535854] cpuidle_enter+0x3c/0x50 [ 7.535859] CPU4: stopping [ 7.535865] do_idle+0x21c/0x2d0 [ 7.535870] CPU7: stopping [ 7.535873] cpu_startup_entry+0x28/0x60 [ 7.535879] CPU5: stopping [ 7.535882] secondary_start_kernel+0x13c/0x1d0 [ 7.535889] CPU6: stopping [ 7.535896] CPU: 4 PID: 0 Comm: swapper/4 Not tainted 5.10.209 #85 [ 7.535899] Hardware name: Rockchip RK3588 EVB4 LP4 V10 Board (DT) [ 7.535902] Call trace: [ 7.535913] dump_backtrace+0x0/0x1f0 [ 7.535921] show_stack+0x1c/0x24 [ 7.535928] dump_stack_lvl+0xe0/0x104 [ 7.535934] dump_stack+0x14/0x30 [ 7.535941] local_cpu_stop+0x74/0x7c [ 7.535947] ipi_handler+0x174/0x2a4 [ 7.535953] handle_percpu_devid_fasteoi_ipi+0x80/0x160
09-14
<think> 我们面对的问题是在Rockchip RK3588 EVB4开发板上运行/sbin/init作为init进程时出现内核恐慌(Kernel panic),错误信息为"Attempted to kill init! exitcode=0x00007f00"。根据错误日志,进程ID为1的init进程在启动时失败导致了系统崩溃。以下将详细分析原因并提供解决方案。 ### 错误分析 1. **错误代码分析**: exitcode=0x00007f00表明init进程以退出状态127结束(0x7f00右移8位得到127)。在Unix系统中,退出码127通常表示"command not found",即找不到指定的命令或程序。这提示/sbin/init可能不存在或无法执行。 2. **硬件平台特性**: Rockchip RK3588使用ARM64架构,其启动流程对根文件系统挂载和init程序路径有特定要求。开发板配置可能需要调整。 3. **可能原因**: - **根文件系统问题**:根文件系统未正确挂载,导致/sbin/init无法访问。 - **init程序缺失**:根文件系统中缺少/sbin/init或符号链接错误。 - **权限问题**:init程序缺少可执行权限。 - **内核配置问题**:内核编译时未启用必要功能(如支持的文件系统、驱动等)。 - **启动参数错误**:内核命令行参数(cmdline)中root=指定的设备或文件系统类型错误。 ### 解决方案 #### 1. 检查根文件系统挂载 - **确认根文件系统设备**: 检查内核命令行参数中root=的值(通过/proc/cmdline查看)。确保设备路径(如/dev/mmcblk0p2)和文件系统类型(如ext4)正确。 ```bash # 在系统启动前于U-Boot中查看或修改cmdline printenv bootargs setenv bootargs root=/dev/mmcblk0p2 rootfstype=ext4 rootwait rw saveenv ``` - **强制检查文件系统**: 若怀疑文件系统损坏,在挂载前使用fsck检查: ```bash fsck.ext4 -y /dev/mmcblk0p2 ``` #### 2. 验证/sbin/init程序 - **确认init存在性**: 挂载根文件系统到临时目录(如/mnt),检查/sbin/init: ```bash mount /dev/mmcblk0p2 /mnt ls -l /mnt/sbin/init ``` 若不存在,需重新安装系统或创建符号链接(例如指向systemd或busybox): ```bash # 若使用systemd ln -s ../lib/systemd/systemd /mnt/sbin/init # 若使用busybox ln -s ../bin/busybox /mnt/sbin/init ``` - **检查权限**: 确保init程序有可执行权限: ```bash chmod +x /mnt/sbin/init ``` #### 3. 调试内核启动流程 - **启用initramfs**: 若根文件系统挂载前需要额外驱动,可构建包含必要工具的initramfs: 1. 使用busybox构建最小文件系统。 2. 将内核模块(如MMC/SD驱动)复制到initramfs。 3. 在内核编译配置中启用INITRAMFS_SOURCE。 - **增加内核日志**: 在内核命令行添加debug参数增强日志输出: ```bash setenv bootargs ... loglevel=7 debug ``` 观察启动日志中VFS挂载根文件系统的详细过程。 #### 4. 内核配置检查 针对RK3588平台,确认以下配置已启用: ```plaintext CONFIG_BLK_DEV_SD=y # SCSI磁盘支持 CONFIG_MMC_SDHCI=y # SDHCI驱动 CONFIG_MMC_SDHCI_OF_ARASAN=y # Rockchip SDHCI控制器 CONFIG_SCSI=y CONFIG_EXT4_FS=y # ext4文件系统 CONFIG_SQUASHFS=y # 若使用squashfs CONFIG_DEVTMPFS_MOUNT=y # 自动挂载/dev ``` 重新编译内核并更新启动镜像。 ### 操作流程图 ```mermaid graph TD A[出现Kernel panic] --> B{检查根文件系统} B --> B1[查看/proc/cmdline参数] B --> B2[fsck修复文件系统] B2 --> C{是否修复成功?} C -->|是| D[验证/sbin/init] C -->|否| E[重新制作文件系统] D --> D1[是否存在且可执行?] D1 -->|是| F[检查内核配置] D1 -->|否| G[安装或链接init] F --> H[重新编译内核] H --> I[更新固件并测试] ``` ### 相关问题 §§相关问题§§ 1. 如何为Rockchip RK3588平台构建支持initramfs的内核? 2. 当根文件系统使用非ext4格式(如squashfs)时需要注意哪些配置? 3. 如何通过U-Boot调试内核启动阶段的根文件系统挂载过程? 4. 在嵌入式Linux中,如何选择替代/sbin/init的轻量级初始化程序? 通过以上步骤应能解决该错误。若问题仍然存在,建议通过串口捕获完整内核日志进一步分析。 </think> 针对Rockchip RK3588 EVB4开发板运行`/sbin/init`时出现的`Kernel panic - not syncing: Attempted to kill init! exitcode=0x00007f00`错误,以下是系统级解决方案: ### 错误根本原因分析 1. **退出码解析**: `exitcode=0x00007f00`表示`init`进程以**状态码127**退出(`0x7f00 >> 8 = 127`)。在Linux系统中,127错误通常表示: - `/sbin/init`二进制文件**缺失** - 文件路径**不正确** - 缺少**执行权限** - 依赖的**动态库缺失**(需验证`ldd /sbin/init`) 2. **平台特性**: RK3588采用**ARM64架构**,需确保: - `init`程序为**aarch64编译版本** - 根文件系统包含**完整ARM64运行时库** - 内核配置启用了**必要驱动**(如MMC/SD卡控制器驱动) --- ### 解决方案 #### 1. 验证根文件系统完整性 ```bash # 在宿主机检查开发板根文件系统 $ mount /dev/sdX /mnt # SDX为存储设备分区 $ ls -l /mnt/sbin/init # 确认文件存在 -rwxr-xr-x 1 root root 1.8M Jan 1 00:00 /mnt/sbin/init # 验证可执行权限和依赖库 $ chroot /mnt /bin/bash # ldd /sbin/init # 检查所有动态库是否存在 # file /sbin/init # 确认架构: ELF 64-bit LSB executable, ARM aarch64 ``` #### 2. 修复内核配置(关键步骤) 在RK3588内核源码目录执行: ```bash $ make menuconfig ``` 启用以下必要选项: ```plaintext General setup → [*] Initial RAM filesystem support (/path/to/initramfs) Initramfs source file # 可选临时方案 Device Drivers → MMC/SD/SDIO support → [*] MMC block device driver [*] Rockchip SDHCI Controller Executable file formats → [*] Kernel support for ELF binaries ``` #### 3. 应急处理(通过U-Boot) 在U-Boot命令行临时启用initramfs: ```bash # 设置内核参数 setenv bootargs "initrd=0x46000000,20M root=/dev/mmcblk0p2 rootwait" saveenv boot ``` #### 4. 硬件相关修复 针对RK3588 EVB4开发板: 1. **检查存储设备分区表**: ```bash # 在U-Boot中验证eMMC/SD识别 mmc list mmc dev 0 # 切换到设备0 mmc part # 显示分区 ``` 2. **调整设备树配置**: 在`rk3588-evb4.dts`中确认SD控制器节点: ```dts &sdhci { status = "okay"; bus-width = <8>; non-removable; mmc-hs400-1_8v; }; ``` --- ### 操作流程图解 ```mermaid graph TD A[内核崩溃] --> B{检查 /sbin/init } B -->|文件缺失| C[重建根文件系统] B -->|权限问题| D[chmod +x /sbin/init] B -->|库缺失| E[添加ARM64库] A --> F{内核配置} F -->|MMC驱动| G[启用 CONFIG_MMC_SDHCI_OF_ARASAN] F -->|文件系统| H[启用 EXT4/SQUASHFS] A --> I{硬件} I -->|eMMC未识别| J[检查PCB电压配置] I -->|分区错误| K[重新分区并格式化] ``` --- ### 相关问题
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值