在没有打印以及ICE无法连接的情况下,如何知道kernel hang的位置

本文介绍两种方法来查看 Linux 内核 printk 缓冲区的内容,包括通过 System.map 文件找到 __log_buf 的地址并在 U-Boot 中读取,以及修改 printk.c 并重新编译内核。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前提是reset板子不会照成memory被reset

方法一(已测试):

1. 打开你的System.map文件,找到symbol: __log_buf

比如:806d6f88 b __log_buf

这里的地址0x806d6f88是虚拟地址,不过是和物理地址一一对应的,

一般双方只差一个最高4位的偏移。本例中__log_buf的物理地址是

0x106d6f88

2. boot板子进入uboot,运行一下命令:

md 0x106d6f88 40

你就能够看到上次的输出了(如下)。


106d6f88: 00000000 00000000 001f0030 c6000000    ........0.......
106d6f98: 746f6f42 20676e69 756e694c 6e6f2078    Booting Linux on
106d6fa8: 79687020 61636973 5043206c 00302055     physical CPU 0.
106d6fb8: 00000000 00000000 007a0090 a6000000    ..........z.....
106d6fc8: 756e694c 65762078 6f697372 2e33206e    Linux version 3.


方法二(未测试)

1. 加入如下的改动:

> diff --git a/kernel/printk.c b/kernel/printk.c index7982a0a..a67a178

> 100644

> --- a/kernel/printk.c

> +++ b/kernel/printk.c

> @@ -661,6 +661,8 @@ static voidcall_console_drivers(unsigned start,

> unsigned end)

>        _call_console_drivers(start_print, end, msg_level);  }

> +extern void printch(const char c);

> +

>  static void emit_log_char(char c)

>  {

>        LOG_BUF(log_end) = c;

> @@ -671,6 +673,8 @@ static void emit_log_char(charc)

>                con_start = log_end - log_buf_len;

>         if(logged_chars < log_buf_len)

>                logged_chars++;

> +

> +      printch(c);

>  }

目的应该是用earlyprintk打印出上次printk的buffer。

2. 加入 CONFIG_DEBUG_LL重新编译kernel

3. 加入earlyprintk到你的bootloader的参数里。

4,然后启动kernel就能看到上次的打印了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值