qcom 平台 Kernel Panic log 的保存

这个功能的实现是同事完成的。我阅读了他的代码后,整理了文档。

基本思路

  1. 注册panic notifier callback,当发生panic时,触发panic处理函数。
  2. 获取一块连续的内存,用于保存panic console,thread log。
    不使用文件系统,以防止是由于文件系统导致的系统panic。
  3. 系统触发warm reset,由于不掉电,内存信息得以保持 。
  4. qcom平台会在sbl中通过boot_sahara_entry, 进入ramdump模式保存发生系统crash时的ram。
    可以在此之前,将内存中保存的panic再次保存起来,此时由于文件系统没有准备好,所以可以添加一个
    分区专门用来保存panic中的信息。
  5. 系统重新启动后,可以读取panic分区中的信息,如果有panic信息,自动读取并生成文件到文件系统中
  6. 这时就可以读取log,分析问题了。

代码实现

1 . kernel 代码添加
注册panic notifier callback,可以参考msm-poweroff.c中关于记录restart_reason的实现

  • device_initcall(panic_handler_init);
    注册一个initcall
  • atomic_notifier_chain_register(&panic_notifier_list, &panic_blk);
    注册panic发生时的回调函数
  • drv_ctx.apanic_log = (void *)__get_free_pages(GFP_KERNEL,get_order(LOG_RAM_SIZE));
    分配一个存储panic log的ram空间
  • np = of_find_compatible_node(NULL, NULL, “qcom,msm-imem-apanic_log_addr”);
    drv_ctx.apanic_log_addr = of_iomap(np, 0);
    获取imem 预定义的panic log ram存储地址
  • writel_relaxed(__pa((unsigned long int)(drv_ctx.apanic_log)),drv_ctx.apanic_log_addr);
    将分配的用以存储panic log的ram地址记录到预定义的imem panic节点里,等待sbl使用。
  • panic_blk.notifier_call = apanic
    panic回调函数,记录panic发生时console和thread信息到apanic_log buffer中。
    kmsg_dump_get_line 获取kmsg console信息
  • dtsi imem device 添加
    apanic_log_addr@18 {
    compatible = “qcom,msm-imem-apanic_log_addr”;
    reg = <0x18 4>;
    };

2 . sbl代码添加

  • IMEM panic 节点定义

    #define SHARED_IMEM_APANIC_LOG_OFFSET 0x18
    #define SHARED_IMEM_APANIC_LOG_ADDR_BASE
    (SCL_IMEM_BASE+SHARED_IMEM_APANIC_LOG_OFFSET)

  • panic分区定义 添加分区定义到:boot_gpt_partition_id.c

  • 在sbl1_pre_dload_procs里添加panic ram -> 分区的保存函数  通过dev_sdcc_write_bytes 保存ram信息到panic 分区

3 . panic分区的添加
在build/partition.xml中参考其他分区添加panic分区

你可能感兴趣的:(qcom 平台 Kernel Panic log 的保存)