Dump the MIPS TLB refill handler

来自Jack's Lab
跳转到: 导航, 搜索

1 动态生成后立即 dump

注意到 arch/mips/mm/tlbex.c 中,在所有 build 函数 (build_xxx_tlb_refill_handler(), build_xxx_tlb_load_handler(), build_xxx_tlb_store_handler(), build_xxx_tlb_modify_handler() ) 的最后都会调用 dump_handler(),其实现在相同的文件里:

static inline void dump_handler(const u32 *handler, int count)
{
    int i;

    pr_debug("\t.set push\n");
    pr_debug("\t.set noreorder\n");

    for (i = 0; i < count; i++)
        pr_debug("\t%p\t.word 0x%08x\n", &handler[i], handler[i]);

    pr_debug("\t.set pop\n");
}


可以直接将 pr_debug( 替换为 printk("<0>" 即能在启动时 dump 出 TLB refill handler: 如dumped 出的 raw data 为:

        .set push
        .set noreorder
        ffffffff80000000        .word 0x07610005
        ffffffff80000004        .word 0x3c1bc000
        ffffffff80000008        .word 0x035bd02f
        ffffffff8000000c        .word 0x3c1b8396
        ffffffff80000010        .word 0x10000023
        ffffffff80000014        .word 0x277ba000
        ffffffff80000018        .word 0x001bd83c
        ffffffff8000001c        .word 0x035bd02f
        ffffffff80000020        .word 0x1000001f
        ffffffff80000024        .word 0x3c1b8396
        ffffffff80000028        .word 0x00000000
        ffffffff8000002c        .word 0x00000000
        .set pop


写一个简单的 C 文件 dtlb.c:

int main()
{
    asm (
        ".set push\n\t"
        ".set noreorder\n\t"
        ".word 0x07610005\n\t"
        ".word 0x3c1bc000\n\t"
        ".word 0x035bd02f\n\t"
        ".word 0x3c1b8396\n\t"
        ".word 0x10000023\n\t"
        ".word 0x277ba000\n\t"
        ".word 0x001bd83c\n\t"
        ".word 0x035bd02f\n\t"
        ".word 0x1000001f\n\t"
        ".word 0x3c1b8396\n\t"
        ".word 0x00000000\n\t"
        ".word 0x00000000\n\t"
        ".set pop\n\t"
        );

        return 0;
}


mips-wrs-linux-gnu-mips64_xlr-glibc_small-gcc -c dtlb.c -o dtlb.o
mips-wrs-linux-gnu-mips64_xlr-glibc_small-objdump -d dtlb.o > dtlb.s


即得之。

另数据转换可在 vim 中用如下命令批量转:

 %s/[0-9a-f]\{16\}\ *\(\.word.*\)/"\1\\n\\t"/g



2 进入系统后 dump

先确定你的 refill exception 的入口:

MIPS32/64R1 的入口都在物理地址 0x0 处

MIPS32/64R2 则要注意 cp0_ebase 寄存器对所有异常基地址的设置

cavium cn3/58xx 实现 MIPS64R2,要留意。

raza xlr732 实现 MIPS64R1,因此直接读 /dev/mem 偏移 0x0 处:

root@rmi_atx_2-1:/root> xxd -l 0x100 -g 4 /dev/mem
0000000: 07130025 3c1bc000 035bd02f 3c1b8397 ...%<....[./<...
0000010: 10000023 277b8000 001bd83c 035bd02f ...#'{.....<.[./
0000020: 3c1b8397 1000001e 277be000 00000000 <.......'{......
0000030: 00000000 00000000 00000000 00000000 ................
0000040: 00000000 00000000 00000000 00000000 ................
0000050: 00000000 00000000 00000000 00000000 ................
0000060: 00000000 00000000 00000000 00000000 ................
0000070: 00000000 00000000 00000000 00000000 ................
0000080: 403a4000 0740001a 403b2000 001bddfa @:@..@..@; .....
0000090: 3c1a8397 037ad82d 403a4000 df7b0000 <....z.-@:@..{..
00000a0: 001ad6fa 335a1ff8 037ad82d 403a4000 ....3Z...z.-@:@.
00000b0: df7b0000 001ad4ba 335a0ff8 037ad82d .{......3Z...z.-
00000c0: 403aa000 df7b0000 335a0ff0 037ad82d @:...{..3Z...z.-
00000d0: df7a0000 df7b0008 001ad1ba 409a1000 .z...{......@...
00000e0: 001bd9ba 409b1800 42000006 42000018 ....@...B...B...
00000f0: 001ad8b8 1000ffc2 00000000 00000000 ................


然后用两条 vim replace 指令处理下:

:%s/\(.*:\ \)\([0-9a-f\ ]*\).*/\2/g
:%s/\([0-9a-f]\{8\}\ \)/".word\ 0x\1\\n\\t"\r/g


就可以得到如下:

".word 0x07610005 \n\t"
".word 0x3c1bc000 \n\t"
".word 0x035bd02f \n\t"
".word 0x3c1b8397 \n\t"

".word 0x10000023 \n\t"
".word 0x277b8000 \n\t"
".word 0x001bd83c \n\t"
".word 0x035bd02f \n\t"

".word 0x3c1b8397 \n\t"
".word 0x1000001e \n\t"
".word 0x277be000 \n\t"
".word 0x00000000 \n\t"

".word 0x00000000 \n\t"
".word 0x00000000 \n\t"
".word 0x00000000 \n\t"
".word 0x00000000 \n\t"


".word 0x00000000 \n\t"
".word 0x00000000 \n\t"
".word 0x00000000 \n\t"
".word 0x00000000 \n\t"
......


包在

int main()
{
        asm (
                <<here>>
        );
}

里,用交叉编译工具编译后,再 objdump:

mips-wrs-linux-gnu-mips64_xlr-glibc_small--gcc -c abc.c -o abc.o
mips-wrs-linux-gnu-mips64_xlr-glibc_small--objdump -d abc.o > abc.s

即得

















个人工具
名字空间

变换
操作
导航
工具箱