说点上节没有讲完的话题
#define access_ok(type,addr,size)type 标识读写操作VERIFY_READ表示地址可读,VERIFY_WRITE表示地址可写
我们 看一段内核代码 (path : arch/arm/include/asm/uaccess.h)
#define access_ok(type,addr,size) (__range_ok(addr,size) == 0)
#ifdef CONFIG_MMU
...
#define __range_ok(addr,size) ({ \
unsigned long flag, roksum; \
__chk_user_ptr(addr); \
__asm__("adds %1, %2, %3; sbcccs %1, %1, %0; movcc %0, #0" \
: "=&r" (flag), "=&r" (roksum) \
: "r" (addr), "Ir" (size), "0" (current_thread_info()->addr_limit) \
: "cc"); \
flag; })
#else
...
#define __range_ok(addr,size) (0)
static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n) { if (access_ok(VERIFY_WRITE, to, n)) n = __copy_to_user(to, from, n); return n; }可以看到他在函数内部做了这种检测
而当我们调用
__copy_to_user __copy_from_user get_user __get_user put_user __put_user时都需要检测用户地址是否可用
KERN_GMERG<0> | 用于紧急消息, 常常是那些崩溃前的消息. |
KERN_ALERT<1> | 需要立刻动作的情形. |
KERN_CRIT<2> | 严重情况, 常常与严重的硬件或者软件失效有关. |
KERN_ERR<3> | 用来报告错误情况; 设备驱动常常使用 来报告硬件故障. |
KERN_WARNING<4> | 有问题的情况的警告, 这些情况自己不会引起系统的严重问题 |
KERN_NOTICE<5> | 正常情况, 但是仍然值得注意. 在这个级别一些安全相关的情况会报告. |
KERN_INFO<6> | 信息型消息. 比如 :打印它们发现的硬件的信息. |
KERN_DEBUG<7> | 用作调试消息. |
#if SIMPLE_DEBUG #define D(...) printk(KERN_DEBUG __VA_ARGS__) #define WAR(...) printk(KERN_WARNING __VA_ARGS__) #else #define D(...) ((void)0) #define WAR(...) ((void)0) #endif在需要调试的时候,我们去定义SIMPLE_DEBUG这个宏,在驱动代码测试都OK可以发行时候,去掉这个定义。
D(“print the log int func:%s line:%d”, __func__ ,__LINE__);当然要修改成有意义的debug信息
D("[process: %s] [pid: %d] xxx\n" , current->comm, current->pid);
struct simple_dev{ char *data; loff_t count; struct cdev cdev; struct semaphore semp; };在open方法中除了上一节看到的那样用一个次设备好来获取结构(有时候会出错 如果我们次设备号不是从0开始分配)
/** * container_of - cast a member of a structure out to the containing structure * @ptr: the pointer to the member. * @type: the type of the container struct this is embedded in. * @member: the name of the member within the struct. * */ #define container_of(ptr, type, member)再解释一下
/*container_of(pointer, container_type, container_fild) we can get the container_type with one number in the container by this function. container_fild is the one of the number in the container_type , pointer point to confain_field type */ temp_dev = container_of(inodp->i_cdev, struct simple_dev, cdev);上边的E文 是我写的 poor English
#define container_of(ptr, type, member) ({ \ const typeof(((type *)0)->member) * __mptr = (ptr); \ (type *)((char *)__mptr - offsetof(type, member)); })