1 .驱动文件编译问题
1.1 如何将驱动文件编译进内核?分析及修改.config defconfig makefie kconfig
1.1 multiple definition of XXX 问题分析
原因:多个源文件中定义了相同名称的函数
1.2 probe 函数没有进入问题
I2C boardinfo中定义的i2c 设备名称与驱动中的名称不一致,导致i2c_add_driver 调用失败
不足:没有使用printk将i2c_add_driver 的调用结果打印出来
遗留问题:1.3 源文件中包含头文件时的路径问题
比如#include <i2c.h> 编译器如何知道编译的是那个目录下的i2c文件?
2 linux sysfs 与kobject
sysfs: 表示系统中设备树的一个文件系统(是处于内存中的虚拟文件系统),提供了kobject对象层次结构的视图。
kobject: linux 设备模型的核心,类似是一个对象类,用于创建对象的层次结构。
PS:多数情况下,驱动程序开发者并不必直接处理kobject,因为kobject是被嵌入到一些特殊结构体中(如在字符设备结构体中的情形),而且会有相关的设备驱动程序在“幕后”管理。但是,kobject,可以出现在设备驱动代码中,或者可以在设备驱动子系统本省中使用它们。
即kobject 通常是嵌入到其他结构中,其单独意义不大,例如嵌入到struct cdev 中。
sys下面的目录和文件反映了整台机器的系统状况,最重要的是devices。
2.1 一个kboject是类型为struct kobject的一个对象
Kobject有一个名字(name)和一个引用计数(reference count)。一个kobject还包含一个父指针(该指针可以使得对象之间可以分层次排列)、一个特殊的类型(即ktype)、一个在sysfs虚拟文件系统里的表示(representation)。
Kobjects基本上并不关注本身,它们通常被嵌入到其他数据结构中,这些数据结构中包含真正受关注的成员。
永远不要让一个数据结构中包含超过1个kobject,如果真的这么做了,那么对该对象的引用计数必定一团糟并且不正确,你的代码也将充满bug,所以千万别这么做。
2.2 一个ktype是 包含kobject的对象 的类型
每一个包含kobject的结构需要一个对应的ktype。当创建和销毁kobject的时候,ktype控制将会发生什么。
2.3 一个kset是一组kobjects
这组kobjects可以属于同一ktype,也可以属于不同的ktypes。Kset是收集kobjects的基本的容器类型。Ksets也包含它们自己的kobjects,不过你可以很安全地忽视那些实现细节,因为kset的核心代码会自动地处理它们自己的kobject。
3 switch case 问题
标准用法是:case 后接break语句;如下例中,则会输出5 4 3 2 1。触摸屏的数据解析中使用了这一不规范用法解析触摸数据。建议使用for循环来代替此处的switch case。
int i =5;
switch(i){
case 5:
printf("5\n");
case 4:
printf("4\n");
case 3:
printf("3\n");
case 2:
printf("2\n);
case 1:
printf("1\n");
break;
}
4 kernal panic 错误
Kernel panic error:
[ 2.631439 C0 swapper/0, 1 ] Initializing freg device.
[ 2.638488 C0 swapper/0, 1 ] ------------[ cut here]------------
[ 2.645111 C0 swapper/0, 1 ] kernel BUG at/home/gavin/p1-code/AndroidRefWs_kk_441_r1_tk_20140108/kernel/hawaii/3.10/fs/proc/generic.c:344!
[ 2.658081 C0 swapper/0, 1 ] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
[ 2.665863 C0 swapper/0, 1 ] Modules linkedin:
[ 2.670928 C0 swapper/0, 1 ] CPU: 0 PID: 1 Comm:swapper/0 Not tainted 3.10.17 #33
[ 2.678985 C0 swapper/0, 1 ] task: db61cac0 ti:db630000 task.ti: db630000
[ 2.686370 C0 swapper/0, 1 ] PC is at proc_register+0x70/0x118
[ 2.692718 C0 swapper/0, 1 ] LR is at _raw_spin_unlock_irq+0x2c/0x4c
[ 3.606842 C0 swapper/0, 1 ] [<c016a3fc>] (proc_create_data+0x74/0x94) from [<c097384c>](freg_init+0x198/0x238)
[ 3.617523 C0 swapper/0, 1 ] [<c097384c>] (freg_init+0x198/0x238) from [<c00085c4>](do_one_initcall+0xcc/0x184)
[ 3.628173 C0 swapper/0, 1 ] [<c00085c4>] (do_one_initcall+0xcc/0x184) from [<c0941b78>](kernel_init_freeable+0x150/0x220)
[ 3.639770 C0 swapper/0, 1 ] [<c0941b78>] (kernel_init_freeable+0x150/0x220) from [<c0674e30>](kernel_init+0x8/0xf8)
[ 3.650848 C0 swapper/0, 1 ] [<c0674e30>] (kernel_init+0x8/0xf8) from [<c000e608>](ret_from_fork+0x14/0x2c)
[ 3.661163 C0 swapper/0, 1 ] Code: e5943024 e3530000159f3098 1a000000 (e7f001f2)
[ 3.669250 C0 swapper/0, 1 ] ---[ end trace019c981d60913d78 ]---
[ 3.675872 C0 swapper/0, 1 ] swapper/0 (1) usedgreatest stack depth: 5476 bytes left
[ 3.684417 C0 kworker/0:1, 30 ] ACCESSORY REMOVED
[ 3.686859 C1 swapper/0, 1 ] Kernel panic - not syncing: Attempted to kill init!exitcode=0x0000000b
[ 3.686859 C1 swapper/0, 1 ]
函数调用链:kernel_init->kernel_init_freeable->do_basic_setup->do_initcalls->do_init_level->do_one_initcall->
Kernelpanic 表明内核中 出现了一种异常情况,可以根据打印信息中的函数调用关系分析原因。打印信息很丰富,后续尽量搞懂。
5 .copy_to_user copy_from_user
内核空间和用户空间的内存不能直接互访,因此借助上述函数完成用户空间到内核空间的拷贝,注意上述函数返回不能被复制的字节数,因此如果完全复制成功,返回值为0.
6. Solaris (读作 /se'laris:/ 或者 /so'le:ris/ 或者 '梭拉瑞斯' )是Sun Microsystems研发的计算机 操作系统。它被认为是UNIX操作系统的衍生版本之一
7.linux 编译时的生成文件
modules.builtin:这个文件列出了所有编译到内核的模块
modules.order:这个文件记录了Makefile中模块出现的顺序
.cmd 文件:编译生成的中间文件,用于连接
8 .dmesg 和kmesg
Linux命令dmesg用来显示开机信息,kernel会将开机信息存储在ring buffer中。若是开机时来不及查看信息,可利用dmesg来查看。开机信息亦保存在/var/log目录中,名称为dmesg的文件里。
此文件用来保存由内核输出的信息,通常由/sbin/klogd或/bin/dmsg等程序使用,不要试图使用查看命令打开此文件;