驱动笔记

    技术2026-08-16  19

    驱动参数的配置方法:

    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/

     

    DEBUG=y ifeq ($(DEBUG),y) DEBFLAGS = -O -g -DSCULL_DEBUG else DEBFLAGS = -O2 endif EXTRA_CFLAGS += $(DEBFLAGS) ifneq ($(KERNELRELEASE),) # call from kernel build system obj-m := scull.o else KERNELDIR ?= /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) modules: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules clean: rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions endif

     

     

    最新回复(0)