1.Linux设备类型:字符设备,块设备,网络设备。
(1)字符设备
作为字节流来处理。至少实现open,close,read,write系统调用。在文件系统的/dev目录下。
(2)块设备
整块IO操作。与字符设备接口不同。在文件系统的/dev目录下。
(3)网络接口
网络接口一般是硬件,也可以是软件,如loopback。并不在文件系统/dev目录下,没有路径,通过名字如eth0来访问。
USB设备可以是字符设备(USB串口),块设备(U盘),网络设备(USB网卡)。
2.内核视图
3. 内核模块注册之后是为了接收接下来的请求,其初始化程序会马上结束。换言之,模块的初始化函数的作用是为后续调用模块函数功能做准备。模块的exit函数告诉内核,不能再调用模块的函数。
这种方法类似于事件驱动的编程,每个内核模块都是事件驱动的。模块的资源在调用exit的时候一定要释放,否则只能在系统重启后才会释放。
内核模块只能调用内核导出的函数,不能调用C的标准库函数,因为不会和libc链接。
内核的函数可以作为两种方式执行:系统调用、中断处理
4.Unix在调用系统调用或发生硬件中断的时候将执行从用户空间转到内核空间。
内核代码在一个进程的上下文中执行系统调用,这个进程代表调用进程,可以访问调用进程的地址空间。
5.打印日志不要太多,可用printk_ratelimit限制
if (printk_ratelimit( ))
printk(KERN_NOTICE "The printer is still on fire\n");
7. 进程突然退出后内核会为每个open的设备调用close函数释放资源。
8. 使用gdb调试内核时有许多限制,例如,不能修改内核数据,不能设置断点和观察点,也不能单步执行。为使gdb调试内核时获取到符号信息,需要编译内核时打开CONFIG_DEBUG_INFO,这样编译的内核会比一般的大许多。
9. kdb(或kgdb)可以可以加断点和修改数据。
10.字符设备指那些必须以串行顺序依次进行访问的设备,如触摸屏、磁带驱动器、鼠标等。块设备可以用任意顺序进行访问,以块为单位进行操作,如硬盘、软驱等。字符设备不经过系统的快速缓冲,而块设备经过系统的快速缓冲。但是,字符设备和块设备并没有明显的界限,如 Flash 设备符合块设备的特点,但是我们仍然可以把它作为一个字符设备来访问。
11. input事件类型
#define EV_SYN 0x00
#define EV_KEY 0x01
#define EV_REL 0x02
#define EV_ABS 0x03
#define EV_MSC 0x04
#define EV_SW 0x05
#define EV_LED 0x11
#define EV_SND 0x12
#define EV_REP 0x14
#define EV_FF 0x15
#define EV_PWR 0x16
#define EV_FF_STATUS 0x17
#define EV_MAX 0x1f
#define EV_CNT (EV_MAX+1)
12.GNU C对标准C进行一系列扩展,以增强标准C的功能。
1)GNU C 允许使用零长度数组,在定义变长对象的头结构时,这个特性非常有用
#define pr_debug(fmt,arg...) \
printk(fmt,##arg)
使用“##”是为了处理arg不代表任何参数的情况,这时候,前面的逗号就变得多余了。EXPORT_SYMBOL(符号名);
EXPORT_SYMBOL_GPL(符号名);
lseek(fd, 0, SEEK_END);