Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1614590
  • 博文数量: 197
  • 博客积分: 10046
  • 博客等级: 上将
  • 技术积分: 1983
  • 用 户 组: 普通用户
  • 注册时间: 2006-08-07 12:36
个人简介

在外企做服务器开发, 目前是项目经理, 管理两个server开发的项目。不做嵌入式好久了。

文章分类
文章存档

2011年(2)

2010年(6)

2009年(18)

2008年(30)

2007年(100)

2006年(41)

分类: LINUX

2007-10-18 15:52:01

文件: copy_xx_user.rar
大小: 2KB
下载: 下载
 
 
【kernel内部基本函数强化训练1 】copy_to_/_from_user()

你们可以对比一下copy_to_user 和 put_user() 之间的对比,  看看copy_to_user()用法的参数,  尤其是那个参数n如何确定。

附件提供了一个例子 , 包括应用程序和module代码。

kernel的buffer仅仅定义了6个字节。
应用程序test_write.c 我仅仅写了3个, 实际上用户buffer有11个字节。 你们可以改变一些数值来判断一下结果。
test_read.c 我也是仅仅读了3个, 尽管buffer可以容纳20个。




注意kernel里面是如何判断 copy_to_user/copy_from_user() 里面的字节个数的。
万一 ,写多了会segmentation fault的。


更多的copy_to_user() / copy_from_user() 用法, 到 sourceinsight里面搜锁。

copy_from_/_to_user() 的函数的返回值 是 0:表示成功 , <0 ,失败。
基本用法:

QUOTE:
if (copy_to_user((void __user *)arg, &info, sizeof(info)))
                return -EFAULT;

无法知道到底写了多少个字节。 如果实在想知道 , 其实就是 参数n  。 n肯定是实现算出来的(比较过的结果)



xx_read() 函数

QUOTE:
static ssize_t device_read(struct file *filp,        /* see include/linux/fs.h   */
                                                        char *buffer,        /* buffer to fill with data */
                                                        size_t length,        /* length of the buffer     */
                                                        loff_t * offset)        /* loff_t  ==   long long */
{
        //        Number of bytes actually written to the buffer
        int bytes_read = 0;
       
        if (*msg_Ptr == 0)
                return 0;

//        while (length && *msg_Ptr) {
//
//                //           kernel  ----> user
//                put_user(*(msg_Ptr++), buffer++);
//
//                length--;
//                bytes_read++;
//        }
       
        /* copy_to_user() 的用法很简单 */
        dbg("msg_Ptr length=%d\n",strlen(msg_Ptr));
        if(copy_to_user(buffer,msg_Ptr,min(strlen(msg_Ptr),length)))
        {
                dbg("copy_to_user() error \n");
                return -EFAULT;
        }
        bytes_read = min(strlen(msg_Ptr),length);
       
        return bytes_read;
}

xx_write() 函数

QUOTE:
static ssize_t
device_write(struct file *filp, const char *buffer, size_t len, loff_t * off)
{
        int bytes_write = 0;
        int max_bytes = sizeof(msg) -1;

        memset(msg,'\0',sizeof(msg));

//        while( *buffer && bytes_write < len && bytes_write < max_bytes )
//        {                       
//                //           kernel <---user
//                get_user(*(msg_Ptr++),buffer++);//msg_Ptr is same
//                bytes_write++;
//        }
        copy_from_user(msg_Ptr,buffer,min( min(strlen(buffer),len), sizeof(msg)-1));
        bytes_write = min( min(strlen(buffer),len), sizeof(msg)-1);
       
        dbg("write %d bytes \n",bytes_write);

        return bytes_write;

}
阅读(5037) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~