您的位置:首页 > 其它

binder 1 kernel开篇

2017-06-06 09:44 429 查看
binder的作用:

config ANDROID_BINDER_IPC
bool "Android Binder IPC Driver"
depends on MMU
default n
---help---
Binder is used in Android for both communication between processes,
and remote method invocation.

This means one Android process can call a method/routine in another
Android process, using Binder to identify, invoke and pass arguments
between said processes.


binder.c

开篇第一句就搞不懂了:

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

贴一篇别人的blog

作者:彭东林 邮箱:pengdonglin137@163.com

在阅读kernel代码的时候,总是看到有很多驱动都在第一行定义pr_fmt,闲来没事,分析了一下, 发现,确实挺方便的。下面记录分享一下。

我们知道,在驱动中可以使用dev_dbg来输出log,在输出的log中会有一些额外的信息,如所属的device的name。

而pr_fmt就可以实现这个目的,先看一个用法(drivers/i2c/i2c-core.c):

#define pr_fmt(fmt) "i2c-core: " fmt

#include <dt-bindings/i2c/i2c.h>
#include <asm/uaccess.h>
#include <linux/acpi.h>
... ...


但是在这个文件中并没有看到pr_fmt被使用。然后,猜测应该是被哪个宏使用了,所以我在include下搜索pr_fmt发现:

include/linux/printk.h:271:    printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__)
include/linux/printk.h:273:    printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__)
include/linux/printk.h:275:    printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__)
include/linux/printk.h:277:    printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
include/linux/printk.h:279:    printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__)
include/linux/printk.h:282:    printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)
include/linux/printk.h:284:    printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
include/linux/printk.h:296:    printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)


然后看一下printk.h:

1 ... ...
2 #ifndef pr_fmt
3 #define pr_fmt(fmt) fmt
4 #endif
5
6 /*
7  * These can be used to print at the various log levels.
8  * All of these will print unconditionally, although note that pr_debug()
9  * and other debug macros are compiled out unless either DEBUG is defined
10  * or CONFIG_DYNAMIC_DEBUG is set.
11  */
12 #define pr_emerg(fmt, ...) \
13     printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__)
14 #define pr_alert(fmt, ...) \
15     printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__)
16 #define pr_crit(fmt, ...) \
17     printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__)
18 #define pr_err(fmt, ...) \
19     printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
20 #define pr_warning(fmt, ...) \
21     printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__)
22 #define pr_warn pr_warning
23 #define pr_notice(fmt, ...) \
24     printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)
25 #define pr_info(fmt, ...) \
26     printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
27
28 #if defined(CONFIG_DYNAMIC_DEBUG)
29 #include <linux/dynamic_debug.h>
30
31 /* dynamic_pr_debug() uses pr_fmt() internally so we don't need it here */
32 #define pr_debug(fmt, ...) \
33     dynamic_pr_debug(fmt, ##__VA_ARGS__)
34 #elif defined(DEBUG)
35 #define pr_debug(fmt, ...) \
36     printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
37 #else
38 #define pr_debug(fmt, ...) \
39     no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
40 #endif
41 ... ...


可以看到,如果驱动中没有定义pr_fmt(fmt),那么,pr_fmt(fmt)就是fmt。

使用pr_fmt的还不少, 这里有几个比较常用的函数: pr_err, pr_info,  如果没有定义CONFIG_DYNAMIC_DEBUG, 那么pr_debug也会使用pr_fmt。

从上面的代码已经看到pr_fmt的作用了吧,就是在用户要输出的log前面添加额外的固定的信息。下面结合gpio_demo.c驱动看一下pr_fmt的几种用法:

1 #define pr_fmt(fmt) "gpio_demo: " fmt
2 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
3 #define pr_fmt(fmt) KBUILD_MODNAME ":%s:%d: " fmt, __func__, __LINE__


 在gpio_demo.c的第一行定义上面的一种, 然后, 在驱动中调用pr_info, 如:

1 static int gpio_demo_probe(struct platform_device *pdev) {
2     struct device *dev = &pdev->dev;
3     int ret = 0;
4     int i = 0;
5     int gpio = -1;
6     gpio_demo_data_t *data = NULL;
7     struct resource *res = NULL;
8     u32 config, pud, drv;
9
10     pr_info("%s enter.\n", __func__);
11 ... ...


下面是 #define pr_fmt(fmt)
"gpio_demo: " fmt 的输出:

[ 1022.623230] gpio_demo: gpio_demo_probe enter.

下面是 #define pr_fmt(fmt)
KBUILD_MODNAME ": " fmt 的输出(KBUILD_MODNAME是模块的名字,可以阅读这个驱动文件的Makefile文件获得):

[ 1088.639631] gpio_demo: gpio_demo_probe enter.

下面是 #define pr_fmt(fmt)
KBUILD_MODNAME ":%s:%d: " fmt, __func__, __LINE__ 的输出:

[ 1135.108534] gpio_demo:gpio_demo_probe:87: gpio_demo_probe enter.

这对输出log确实比较方便。

这里的 KBUILD_MODNAME又是怎么回事?
https://yhcting.wordpress.com/2012/01/09/kernel-how-to-know-kbuild_modname-of-each-files/


[Kernel] How to know KBUILD_MODNAME of each files.



Kernel build system defines KBUILD_MODNAME automatically from each Makefile.

You can easily find below string from build command of each files of modules.
-D"KBUILD_MODNAME=KBUILD_STR(xxxxx)"
('xxxxx' is given module name)


This name xxxxx comes from Makefile.

Below is simple example.
[ in Makefile ]
xxxxx-y := a.o b.o c.o d.o


In above case, KBUILD_MODNAME of a.c, b.c, c.c and d.cbecomes xxxxx.

This can be easily confirmed by checking command line of each objects – a.o, b.o, c.o and d.o.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: