驱动参数的配置方法:
1 编译时间通过改变的宏.
2 在模块加载时设定
3 使用 ioctl 在运行时改变当前值和缺省值.
用户空间与内核空间的拷贝
unsigned long copy_to_user(void __user *dst, const void *src, unsigned long len);
unsigned long copy_in_user(void __user *dst, const void __user *src, unsigned long len);
用户空间指针当运行于内核模式可能根本是无效的. 可能没有那个地址的映射, 或者它可能指向一些其他的随机数据.
这 2 个函数的角色不限于拷贝数据到和从用户空间: 它们还检查用户空间指针是否有效. 如果指针无效, 不进行拷贝; 如果在拷贝中遇到一个无效地址, 另一方面, 只拷贝部分数据. 在 2 种情况下, 返回值是还要拷贝的数据量.代码查看这个错误返回, 并且如果它不是 0 就返回 -EFAULT 给用户.
内核调试:
CONFIG_DEBUG_INFO
这个选项使得内核在建立时包含完整的调试信息. 如果你想使用 gdb 调试内核, 你将需要这些信息. 如果你打算使用 gdb, 你还要激活
CONFIG_FRAME_POINTER.
CONFIG_DEBUG_DRIVER
在"Device drivers"下. 打开了驱动核心的调试信息, 可用以追踪低层支持代码的问题. 我们在第 14 章查看驱动核心.
CONFIG_INPUT_EVBUG
这个选项(在"Device drivers/Input device support"下)打开输入事件的详细日志. 如果你使用一个输入设备的驱动, 这个选项可能会有用.然而要小心这个选项的安全性的隐含意义: 它记录了你键入的任何东西,包括你的密码.
定制自己的调试(LINUX 下可用):
#undef PDEBUG /* undef it, just in case */
#ifdef THIS_DEBUG
# ifdef __KERNEL__
/* This one if debugging is on, and kernel space */
# define PDEBUG(fmt, args...) printk( KERN_DEBUG "My driver: " fmt, ## args)
# else
/* This one for user space */
# define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args)
# endif
#else
# define PDEBUG(fmt, args...) /* not debugging: nothing */
#endif
追踪调试工具:
strace 命令时一个有力工具, 显示所有的用户空间程序发出的系统调用. 它不仅显示调用, 还以符号形式显示调用的参数和返回值. 当一个系统调用失败,错误的符号值(例如, ENOMEM)和对应的字串(Out of memory) 都显示.
strace ls /dev > /dev/null
strace -o test.log -tT -p 2212
源码树之外编译内核模块:
-C表示要求make先切换到-C指定的目录. SUBDIRS(也可以用M代替SUBDIRS)使make在编译内核模块之前回到当前目录.
整个编译过程实际上是执行-C指定的内核源码树的Makefile, 并通过SUBDIR指定你要编译的内核源文件的目录.
丫丫呸的,DEBUG=y 以后多了一个空格,让我调试了半天……
内核模块的编译,大部分工作是由内核源码树完成的,编译很重要的一步就是指定源码树目录。可以查阅/Documentation/kbuild/