1.2-kernel探索of读取过程2

探索kernel3.18设备树读取过程以及driver的match过程2

(由于个人原因没按时发布,flag很危险呐)

上一篇探索到了match的过程,1形成了自己的打印函数思路,2知道了dump_stack()函数,3缩小了of读取函数的范围。

本篇则通过dump_stack()函数打印出来的函数一个一个找下去,看会不会找到哪个地方读取of


[    4.664679] <6>-(4)[1:swapper/0][] dump_backtrace+0x0/0x190

[    4.664688] <6>-(4)[1:swapper/0][] show_stack+0x14/0x1c

[    4.664697] <6>-(4)[1:swapper/0][] dump_stack+0xbc/0xf8

[    4.664706] <6>-(4)[1:swapper/0][] __of_match_node+0xa8/0xe8

[    4.664714] <6>-(4)[1:swapper/0][] of_match_node+0x38/0x5c

[    4.664721] <6>-(4)[1:swapper/0][] of_match_device+0x18/0x28

[    4.664731] <6>-(4)[1:swapper/0][] platform_match+0x4c/0xb8

[    4.664739] <6>-(4)[1:swapper/0][] __driver_attach+0x3c/0xb8

[    4.664747] <6>-(4)[1:swapper/0][] bus_for_each_dev+0x58/0x98

[    4.664754] <6>-(4)[1:swapper/0][] driver_attach+0x30/0x38

[    4.664761] <6>-(4)[1:swapper/0][] bus_add_driver+0x128/0x23c

[    4.664769] <6>-(4)[1:swapper/0][] driver_register+0x74/0x138

[    4.664777] <6>-(4)[1:swapper/0][] __platform_driver_register+0x60/0x68

[    4.664785] <6>-(4)[1:swapper/0][] mtkfb_init+0x8c/0x168

[    4.664792] <6>-(4)[1:swapper/0][] do_one_initcall+0xec/0x238

[    4.664800] <6>-(4)[1:swapper/0][] kernel_init_freeable+0x14c/0x218

[    4.664809] <6>-(4)[1:swapper/0][] kernel_init+0x14/0x194

[    4.664814] <6>-(4)[1:swapper/0]fuhua-checkcode-score = 1073741823

现在是从a5a_cn_import/kernel3.18/driver/base/dd.c中的__driver_attach中打印出了device->of_node->properties->value,所以应该从bus_for_each_dev往上追溯dev的值。
但如果没有drv的限制,会不会出现value又为空而kernel又处理不了的情况呢?
所以现在急需知道如何让kernel跳过处理"Unable to handle kernel NULL pointer dereference at virtual address 00000020"
现在就绕不过上一篇的mark了
我们可以先探索一下c语言的try catch机制(c语言的异常处理机制),然后看这个办法是否可行(在尝试异常处理机制之前,尝试过用ISR_ERR函数,但是并没有太多的用处)
猜想异常处理机制和堆栈的关系,只能返回堆栈里面的异常?不然就崩溃?goto语句
发现setjmp这个函数根本不能使用,所以只能继续往上看了~
追溯到bus_for_each_dev这段代码,发现里面的dev都是从klist_iter_init_node函数里面读取出来的,所以需要查清楚该函数做了什么
通过查找资料,klist只是kernel三大链表里面的一个,list_head,hlist,klist。所以推断这个函数只是单纯操作klist的,对of没有太多涉及。

网上找到一篇和我想做同样事情的blog,不过是基于3.14的,通过一些验证发现说的一些函数并没有调用到,难道是已经做了修改?

经过一些波折,还是打印除了populate函数的log,处理方式是重新生成obj文件(暂时是不知道原因的,可能和make文件有关系)

现在是将child打印出来看看

PS: 这个populate函数是根据网上查到的,由于之前验证没有打出log,所以之前以为是假的,但是通过log看到populate这个函数的确是被调用了,而且整个代码里面就只有两处,所以验证到了是因为out的obj问题。

现在由于没有打印出来mtkfb这个关键字,所以还在继续寻找如何打印出来子节点什么的,刚刚因为搜索soc关键字所以又走了岔路,所以我们现在回来继续看看tree的节点是怎么构建的。

根据log和populate这个函数里面的逻辑,总算是打印出来了似乎是读取的log,在of_platform_bus_create()for_each_child_of_node(bus, child)下面,打印出child->properties->value
另外of_platform_bus_create居然还是递归调用~~~好久没看到这种了

首先,这个函数不是在bus match mtkfb_driver的时候出现的,是在之前出现的,然后由于在log当中也发现了之前打印的log,所以这个函数可能走的是上一篇文章探索的主要函数之前的流程, 我们先探索一下log,看具体的调用顺序,然后再结合上一篇形成一个总体的概述。

那么先解决第一个疑问,到底有没有真正找到创建device_node的地方呢,我们可以在log之前打印一次child->properties->value如果为null就可以证明之前是没有创建这个节点的,如果有则证明还在前面;当然根据经验,基本上就是这个地方了,后面再去验证吧。如果继续深挖下去就是哪里将设备树加载进来的,以及通过怎样的代码读取的,是否在这些个函数里面呢?这里先mark一下,以后有时间有兴趣有需求再探索

第二个点就是of_platform_bus_create()函数的调用顺序以及该函数和mtkfb_match关系或者调用顺序(关系我只能想到前后关系,前置条件等关系)
那么of_platform_bus_create()的函数调用顺序是怎样的呢?我们通过log可以看到有打印出'mediatek,mtk'之前有dump_stack的影子,log如下:

[    1.935095] <7>-(7)[1:swapper/0]CPU: 7 PID: 1 Comm: swapper/0 Not tainted 3.18.35+ #12

[    1.936079] <7>-(7)[1:swapper/0]Hardware name: MT6738 (DT)

[    1.936763] <7>-(7)[1:swapper/0][name:traps&]Call trace:

[    1.937435] <7>-(7)[1:swapper/0][] dump_backtrace+0x0/0x190

[    1.938324] <7>-(7)[1:swapper/0][] show_stack+0x14/0x1c

[    1.939172] <7>-(7)[1:swapper/0][] dump_stack+0xbc/0xf8

[    1.940019] <7>-(7)[1:swapper/0][] __of_match_node+0x90/0xb4

[    1.940918] <7>-(7)[1:swapper/0][] of_match_node+0x38/0x5c

[    1.941796] <7>-(7)[1:swapper/0][] of_match_device+0x18/0x28

[    1.942698] <7>-(7)[1:swapper/0][] platform_match+0x4c/0xb8

[    1.943586] <7>-(7)[1:swapper/0][] __device_attach+0x2c/0xb4

[    1.944486] <7>-(7)[1:swapper/0][] bus_for_each_drv+0x54/0x94

[    1.945397] <7>-(7)[1:swapper/0][] device_attach+0xb0/0xcc

[    1.946275] <7>-(7)[1:swapper/0][] bus_probe_device+0x94/0xb8

[    1.947188] <7>-(7)[1:swapper/0][] device_add+0x438/0x518

[    1.948055] <7>-(7)[1:swapper/0][] of_device_add+0x50/0x88

[    1.948934] <7>-(7)[1:swapper/0][] of_platform_device_create_pdata+0x78/0xc8

[    1.950007] <7>-(7)[1:swapper/0][] of_platform_bus_create+0xdc/0x490

[    1.950993] <7>-(7)[1:swapper/0][] of_platform_bus_create+0x460/0x490

[    1.951992] <7>-(7)[1:swapper/0][] of_platform_populate+0x48/0xb0

[    1.952949] <7>-(7)[1:swapper/0][] arm64_device_init+0x20/0x2c

[    1.953869] <7>-(7)[1:swapper/0][] do_one_initcall+0xec/0x238

[    1.954780] <7>-(7)[1:swapper/0][] kernel_init_freeable+0x14c/0x218

[    1.955758] <7>-(7)[1:swapper/0][] kernel_init+0x14/0x194

[    1.956622] <7>-(7)[1:swapper/0]fuhua-checkcode-score = 1073741823

[    1.957538] <5>-(5)[1:swapper/0]CPU: 5 PID: 1 Comm: swapper/0 Not tainted 3.18.35+ #12

[    1.958523] <5>-(5)[1:swapper/0]Hardware name: MT6738 (DT)

[    1.959206] <5>-(5)[1:swapper/0][name:traps&]Call trace:

[    1.959873] <5>-(5)[1:swapper/0][] dump_backtrace+0x0/0x190

[    1.960763] <5>-(5)[1:swapper/0][] show_stack+0x14/0x1c

[    1.961609] <5>-(5)[1:swapper/0][] dump_stack+0xbc/0xf8

[    1.962454] <5>-(5)[1:swapper/0][] platform_match+0xa4/0xb8

[    1.963343] <5>-(5)[1:swapper/0][] __device_attach+0x2c/0xb4

[    1.964243] <5>-(5)[1:swapper/0][] bus_for_each_drv+0x54/0x94

[    1.965155] <5>-(5)[1:swapper/0][] device_attach+0xb0/0xcc

[    1.966033] <5>-(5)[1:swapper/0][] bus_probe_device+0x94/0xb8

[    1.966945] <5>-(5)[1:swapper/0][] device_add+0x438/0x518

[    1.967813] <5>-(5)[1:swapper/0][] of_device_add+0x50/0x88

[    1.968691] <5>-(5)[1:swapper/0][] of_platform_device_create_pdata+0x78/0xc8

[    1.969765] <5>-(5)[1:swapper/0][] of_platform_bus_create+0xdc/0x490

[    1.970752] <5>-(5)[1:swapper/0][] of_platform_bus_create+0x460/0x490

[    1.971750] <5>-(5)[1:swapper/0][] of_platform_populate+0x48/0xb0

[    1.972705] <5>-(5)[1:swapper/0][] arm64_device_init+0x20/0x2c

[    1.973626] <5>-(5)[1:swapper/0][] do_one_initcall+0xec/0x238

[    1.974537] <5>-(5)[1:swapper/0][] kernel_init_freeable+0x14c/0x218

[    1.975514] <5>-(5)[1:swapper/0][] kernel_init+0x14/0x194

接下来需要查证两个问题,一个是dump_stack()是在哪里调用的,二是of_platform_bus_create的调用顺序。

一:首先我们搜索一下dump_stack的调用,第一个是drivers/base/platform.c里的platform_match()里面调用了一次 另一个看log应该y也是,当屏蔽了之后发现drivers/of/base.c在前调用,drivers/base/platform.c在后面调用。结合log,发现有一个value是'mediatek,dispsys'```,所以猜想是匹配到了调用的吧,那么就可以看出来这一条线也是有点奇怪的,可能也是在交叉的

也就是说中间有一条没走fuhua-checkcode-device_attcch_else 这条线,这条线前后打出来的child是'mediatek,mdp_color''mediatek,dispsys'

那么现在引申出另一个问题,能进入match的compitable又是哪一个呢?(这一个问题在完成第二点之后再验证)

二: 在加载了'mediatek,mtkfb'的地方打印dump_stack()
log如下:

[    1.723465] <6>-(6)[1:swapper/0][] dump_stack+0xbc/0xf8

[    1.724313] <6>-(6)[1:swapper/0][] of_platform_bus_create+0x498/0x4b4

[    1.725311] <6>-(6)[1:swapper/0][] of_platform_populate+0x48/0xb0

[    1.726268] <6>-(6)[1:swapper/0][] arm64_device_init+0x20/0x2c

[    1.727189] <6>-(6)[1:swapper/0][] do_one_initcall+0xec/0x238

[    1.728100] <6>-(6)[1:swapper/0][] kernel_init_freeable+0x14c/0x218

[    1.729079] <6>-(6)[1:swapper/0][] kernel_init+0x14/0x194

从log看,调用的顺序是kernel_init->kernel_init_freeable->arm64_device_init->of_platform_populate->of_platform_bus_create 结合上一篇我们可以发现都有do_one_initcall这个函数,所以可以看一下是否有先后顺序,发现这个函数的调用也比较特别,在for循环里面调用的fn,所以通过打印的时间来看是of_platform_populatemtkfb_init(void)之前调用的。

至此,读取设备树的流程基本清楚了,现在可以针对of_platform_populate()这个函数进行进一步的解读,解读完成之后基本能回答第一篇的问题3了。

你可能感兴趣的:(1.2-kernel探索of读取过程2)