Android的ram_console和last_kmsg

ram_console和last_kmsg是Android加入到kernel中的一个Debug功能。


实现:

      android要求平台提供一块固定的内存,作为ram_console的存储空间。然后通过“代码:register_console(&ram_console);”,将ram_console注册到printk输出的console_list中去,所以printk会时时向ram_console中输出kernel log。在ram_console头部有一个“代码:RAM_CONSOLE_SIG”的签名,每次android设备启动的时候,会check头部的签名是否正确。如果正确,那就会将ram_console中的内容保起来,生成一个/proc/last_kmsg的节点,用来查看上次最后的kernel log。如果不正确,就不会生成last_kmsg。


作用:

    ram_console和last_kmsg的作用是用来分析重启的原因。

    1. 如果是kernel panic造成的重启,则可以在last_kmsg中panic的现场。

    2. 如果人为的重启,则有机会在last_kmsg中找到一定线索。

    3. 如果没有last_kmsg,说明系统一定掉过电。可以作为分析重启原因的一个重要线索。


探索:

    那么问题来了,平台是如何为ram_console提供一块固定内存的呢?

    我们先来看MTK平台:

    MTK平台直接给了一个虚拟地址:CONFIG_MTK_RAM_CONSOLE_ADDR=0xF900DC00

    然后我们找到了:(说明MTK平台将SOC的SRAM中的64K映射到了kernel虚拟地址中的0xF9000000-0xF9010000)

    #define INTER_SRAM 0xF9000000

    static struct map_desc mt_io_desc[] __initdata =
{
......

    {
        /* virtual 0xF9000000, physical 0x00100000 */
        .virtual = INTER_SRAM,
        .pfn = __phys_to_pfn(0x00100000),
        .length = SZ_64K,
        .type = MT_MEMORY_NONCACHED
    },
......

void __init mt_map_io(void)
{
    iotable_init(mt_io_desc, ARRAY_SIZE(mt_io_desc));
}
......

MACHINE_START(MT6582, "MT6582")
    .atag_offset    = 0x00000100,
    .map_io         = mt_map_io,
    .init_irq       = mt_init_irq,
    .timer          = &mt6582_timer,
    .init_machine   = mt_init,
    .fixup          = mt_fixup,
    .restart        = arm_machine_restart,
    .reserve        = mt_reserve,
MACHINE_END
    最后我们来看一下这部分内存在内核虚拟内存layout中的哪个部分:

    我们来看一下kernel/Documentation/arm/memory.txt

    VMALLOC_START   VMALLOC_END-1   vmalloc() / ioremap() space.
                                         Memory returned by vmalloc/ioremap will
                                         be dynamically placed in this region.
                                         Machine specific static mappings are also
                                         located here through iotable_init().
                                         VMALLOC_START is based upon the value
                                         of the high_memory variable, and VMALLOC_END
                                         is equal to 0xff000000.

    比较明显是被映射到了vmalloc区域。


    那我们再看一个FSL平台的实现:

ram_console.c

    static int ram_console_driver_probe(struct platform_device *pdev)
{
......

struct resource *res = pdev->resource;

......

buffer = ioremap(res->start, buffer_size);


arch/arm/mach-mx6/board-mx6q_sabrelite.c

static void __init mx6q_sabrelite_reserve(void)
{

......

#ifdef CONFIG_ANDROID_RAM_CONSOLE
        phys = memblock_alloc_base(SZ_128K, SZ_4K, SZ_1G);
        memblock_remove(phys, SZ_128K);
        memblock_free(phys, SZ_128K);
        ram_console_resource.start = phys;
        ram_console_resource.end   = phys + SZ_128K - 1;
#endif
......

MACHINE_START(MX6Q_SABRELITE, "Freescale i.MX 6Quad Sabre-Lite Board")
        /* Maintainer: Freescale Semiconductor, Inc. */
        .boot_params = MX6_PHYS_OFFSET + 0x100,
        .fixup = fixup_mxc_board,
        .map_io = mx6_map_io,
        .init_irq = mx6_init_irq,
        .init_machine = mx6_sabrelite_board_init,
        .timer = &mx6_sabrelite_timer,
        .reserve = mx6q_sabrelite_reserve,
MACHINE_END

那么FSL平台是的地址是被reserve起来了。

  • 2
    点赞
  • 0
    评论
  • 9
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值