码迷,mamicode.com
首页 > 其他好文 > 详细

通过JTAG对比内核启动后text/rodata段内容

时间:2019-05-27 19:26:16      阅读:111      评论:0      收藏:0      [点我收藏+]

标签:导出   代码段   代码   二进制   define   system   ade   获取   col   

关键词:vmlinux、strip、dump、_text、__end_rodata等等。

 

在日常的调试中,可能会在某些情况下踩到内核重要的数据,比如代码段或者rodata之类。

这种情况下,需要确认这些数据是否异常。

所谓的异常就是从DDR中读出的数据能否和vmlinux对上。

1. 准备vmlinux数据

原始的vmlinux文件,需要strip:

strip vmlinux -o vmlinux_stripped

然后去掉vmlinux的0x1000头部。

dd if=vmlinux_stripped of=vmlinux_stripped_noheader bs=4096 skip=1

最终得到的文件vmlinux_stripped_noheader就是加载到内核中运行的可执行文件。

2. 从DDR中导出数据

连接上JTAG,然后通过dump memory将DDR中数据导出。

dump memory kernel.bin 0x8000000 0x809c7200

 其中0x80000000是内核执行的起始地址,0x809c7200可以从System.map中获取,也即_end值。

3. 对比数据

从下图可以看出,在内核启动之后不变的数据部分是代码段(_text <--> _etext)和只读数据段(__start_rodata <--> __end_data)。

技术图片

在System.map中找到如下几个关键地址:

...
80049000 T _text
...
806af4e8 T _etext
...
806b0000 R __start_rodata
...
80909000 R __end_rodata
...

在从_text到__end_rodata中间的数据,在整个运行期间是不会改变的。

但是存在一个特殊的RO_AFTER_INIT_DATA段,这部分数据在init初始化之后就不会改变。但是仍然和vmlinux是不一样的。

#ifndef RO_AFTER_INIT_DATA
#define RO_AFTER_INIT_DATA                        \
    __start_data_ro_after_init = .;                        *(.data..ro_after_init)                            __end_data_ro_after_init = .;
#endif

从DDR中导出_text到__end_rodata之间的数据:

dump memory kernel.bin 0x80049000 0x80909000

从stripped之后的vmlinux中截取_text到__end_rodata之间的数据:

dd if=vmlinux_stripped of=vmlinux_stripped_noheader bs=4096 skip=74 count=2240

0x8004900对应73个页面,但是还需要去掉1个页面的头,所以一共是74个页面。

0x80909000-0x8004900=0x8c000,即一共2240个页面。

在BeyondCompare中进行二进制比较如下:

技术图片

 

通过JTAG对比内核启动后text/rodata段内容

标签:导出   代码段   代码   二进制   define   system   ade   获取   col   

原文地址:https://www.cnblogs.com/arnoldlu/p/10932267.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!