一,前言
动手写linux驱动(6)--Apple的学习笔记基本上已经完成我之前理论复习的内容了,开始进入内核驱动了。我之前动手写驱动系列都不算内核驱动,内核驱动我理解要用内核总线的,或者通过配置项即可完成的。所以今天先将applepaper通过设备树挂载在platform虚拟总线上去。
工程9源码在我的gitee上https://gitee.com/applecai/linux-driver-study
二,遇到问题
- 一开始module_platform_driver和module_init的关系忘记了,复习了下module_platform_driver包含了module_init,并且调用了platform_driver_register/platform_driver_unregister。在下面的ftrace中也可以看到详细调关系。
- 我沿用了工程8的代码,无意发现了bug,insmod后rmmod报错。原因是add_timer还没有开启我在rmmod就del_timer了。所以将它注释掉了。
- 一开始我在dts添加完成后,我记得要到node下可以看到他的driver连接,接着我好像没找到。
# cd /sys
# ls
block class devices fs module
bus dev firmware kernel power
# find . -name "applepaper*"
./devices/virtual/apple_class/applepaper7
./devices/virtual/apple_class/applepaper8
./devices/virtual/apple_class/applepaper6
./class/apple_class/applepaper7
./class/apple_class/applepaper8
./class/apple_class/applepaper6
./bus/platform/drivers/applepaperV1
./module/applepaper9
原来是乌龙,其实我dts添加的是正确的。设备都添加成功了,就说明probe函数起作用了呀!保险起见我用ftrace看了下调用关系。
# mount -t debugfs nodev /sys/kernel/debug
# cd /sys/kernel/debug/tracing
# echo 0 > tracing_on
# echo device_create > set_ftrace_filter
# echo function > current_tracer
# echo func_stack_trace > trace_options
# echo 1 > tracing_on
# insmod /usr/study/applepaper9.ko
[ 145.010271] Registered character driver
[ 145.014626] Registered character driver
[ 145.018718] Registered character driver
# echo 0 > tracing_on
# cat trace | head -40
# tracer: function
#
# entries-in-buffer/entries-written: 6/6 #P:1
#
# _-----=> irqs-off
# / _----=> need-resched
# | / _---=> hardirq/softirq
# || / _--=> preempt-depth
# ||| / delay
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |
insmod-116 [000] .... 145.009853: device_create <-applepaper_probe
insmod-116 [000] .... 145.009872:
=> applepaper_probe
=> platform_drv_probe
=> really_probe
=> driver_probe_device
=> device_driver_attach
=> __driver_attach
=> bus_for_each_dev
=> driver_attach
=> bus_add_driver
=> driver_register
=> __platform_driver_register
=> applepaper_driver_init
=> do_one_initcall
=> do_init_module
=> load_module
=> sys_finit_module
=> ret_fast_syscall
=> 0xbee63c80
insmod-116 [000] .n.. 145.014306: device_create <-applepaper_probe
insmod-116 [000] .n.. 145.014315:
=> applepaper_probe
=> platform_drv_probe
=> really_probe
=> driver_probe_device
=> device_driver_attach
=> __driver_attach
=> bus_for_each_dev
我做的设备树完全正确。主要是设备名字我改成了paper0。少了apple,导致一开始我搜索applepaper路径没有搜索到。哈哈~
三,测试效果
/sys/platform的总线下能看到paper0设备,然后它的driver指向了bus/platform/drivers中的applepaperV1。
static const struct of_device_id applepaper_match[] = {
{ .compatible = "am335x,applepaper"},
{ },
};
static struct platform_driver applepaper_driver = {
.driver = {
.name = "applepaperV1",//KBUILD_MODNAME,
.of_match_table = applepaper_match,
},
.probe = applepaper_probe,
.remove = applepaper_remove,
};
module_platform_driver(applepaper_driver);