首页 > 编程知识 正文

linux cat命令详解,linux find 查找文件

时间:2023-05-04 21:25:47 阅读:108757 作者:113

《copytouser和copyfromuser函数分析》由会员共享,可在线阅读。 更多相关《copytouser和copyfromuser函数分析(10页珍藏版)》请在金锺文库搜索。

1、在内核学习中遇到很多非常有趣的函数,而且可以沿着一个函数引出很多相关函数。 copy_to_user和copy_from_user是进行驱动程序相关编程时经常遇到的两个函数。 由于内核空间和用户空间的内存不能直接互访,因此通过函数copy_to_user ()完成从用户空间到内核空间的复制,通过函数copy_from_user ()完成从内核空间到用户空间的复制让我们详细看看这两个函数的经过。 首先,我们来看看这两个函数在源文件中是如何定义的。/arch/i386/lib/user copy.cunsignedlongcopy _ to _ user (void _ use。

2、r *to,const void *from,unsignedlongn(might_sleep ); bug_on(long ) n addr_limit.seg; 闪光灯; (u33 ) addr ) u33 ) size=) u33 ) current-addr_limit.seg判断上式是否成立,不成立时表示地址有效,返回零; 否则,返回非零的下一个函数是最重要的函数,实现复制工作。 _copy_to_user(to,from,n )其实现方法如下(/include/asm-i386/uaccess.h中) ) (静态_ )。

3、nsignedlong _ must _ check _ copy _ to _ user * to,const void *from,unsigned long n ) might _ sleep 有一个_always_inline宏,其内容为inline,为一个_must_check,其内容在gcc3和gcc4的版本中为_ attribute _ (warn _ unused _ ched )

4、如果由IC(to,from,n )完成复制操作,则此函数将在/include/asm-i386/uaccess.h中实现,如下所示: static _ always _ inline unsigned long _ must _ check _ copy _ to _ _。 unsigned long n (if (builtin _ constant _ p ) n ) unsigned long ret; sitch(n ) case1:_put_user_size(* ) u8* ) from,) u8 _user * ) to,1,ret。

五、一; 返回; case 2: _ put _ user _ size (* (u16 * ) from,) u16 _user * ) to,2,ret,2 ); 返回; case 4: _ put _ user _ size (* (u32 * ) from,) u32 _user * ) to,4,ret,4 ); 返回; return_copy_to_user_ll(to,from,n ); 这里,_builtin_constant_p(n )是gcc的嵌入函数,_builtin_constant_p用于判断其值是否为编译时的常熟,参数n的值为常数

6、 当参数为常数时,许多计算和操作都有更优化的实现。 GNU C只能编译常量版本或非常量版本,具体取决于上述方法中的参数是否为常量。 这样可以在参数为常量的情况下编译优化的代码,同时失去通用性。 如果n为常数1、2或4,则选择swith执行复印动作。 副本位于/include/asm-i386/uaccess.h上,网址为# ifdef config _ x86 _ WP _ works _ ok _ chk _ user _ ptr (ptr ); sitch(si。

7、ze ) case1:_put_user_ASM(x,ptr,retval,b,b,iq,errret ); 黑; case2:_put_user_ASM(x,ptr,retval,w,w,ir,errret ); 黑; case4:_put_user_ASM(x,ptr,retval,l,ir,errret ); 黑; case 8: _ put _ user _ u64 (type of _ (* ptr ) ) x )、ptr、retval ); 黑; default: _put_user_bad (; wile(0) #else#define _put_user_size(x ) x,pt。

8、r、size、retval、errret(do_typeof_(* ) ptr ) _pus_tmp=x; retval=0; unlikely (copy _ to _ user _ ll ) ptr,_pus_tmp,size!=0) retval=errret; while(0) #endif其中_put_user_asm是宏,复制工作由以下行内汇编完成(/include/asm-i386/uaccess.h中) :

9、volatile _ (1: movi type % rtype 1,%2n 2:n .section .fixup,axn 3: movl %3, % 0nj mp2bn.previous n.Sect IOUs 3bn.previous :=r (err ) : ltype (x ),m ) m ) addr ),I(errret ),0 )或更大的为了在复制int等的数据时考虑效率,另一方面,如果n不是上述那样的常数,则进行数据块区域的复制,如下(/arch/i386/lib/use )。

10、rcopy.c (unsigned long _ copy _ to _ user _ ll ) void_user*to,const void *from,unsigned long n ) bug _ on unun int retval; struct page *pg; void *maddr; if(len ) len=n; survive : down _ read (current-mm-mmap _。

11、sem; retval=get_user_pages(current,current-mm,) unsigned long ) to,1,1,0,pg,NULL ); if(retval=-enomemcurrent-PID=1) up _ read (current-mm-mmap _ SEM ); blk_congestion_wait(write,HZ/50 ); goto survive; if (还原!=1) up_read(current-mm-mmap_SEM ); 黑; maddr=kmap_atomic(pg,KM_USER0); 机械。

12、(maddr offset,from,len ) kunmap_atomic(maddr,KM_USER0); set_page_dirty_lock(pg; put_page(pg; up_read(current-mm-mmap_SEM ); 来自=len; to =len; n -=len; 返回n; #endifif(movsl_is_ok(to,from,n ) _copy_user ) to,from,n ); elsen=_copy_user_Intel(to,from,n ); 返回n; export_symbol(copy_to_user_l。

13、l; copy_from_user函数的实现如下所示。 unsigned long copy _ from _ user (void * to,const void _user *from,unsigned long n ) might_ )。 错误_on(long ) n 0 ); if(access_ok ) verify_read,from,n ) n=_copy_from_user(to,from,n ); ELSEmemset(to,0,n ); 返回n; export_symbol(copy_from_user; 其实现方法与copy_to_user函数的实现方法相似。 就不会累了。 以上是copy_to_user和copy_from_user这两个函数的工作方式,这些进行简单的分析和跟踪。 细节部分还有待研究。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。