linux put函数,Linux内核中的get_user和put_user

当标号1处发生缺页异常时,系统将调用do_page_fault提交物理页面,然后跳到__get_user_bad继续执行。get_user函数如果成果执行则返回1,否则返回-EFAULT。

put_user用于将内核空间的一个简单类型变量x拷贝到p所指向的用户空间。该函数可以自动判断变量的类型,如果执行成功则返回0,否则返回-EFAULT。下面给出它们的定义(linux/include/asm-arm/uaccess.h)。

extern int __put_user_1(void *, unsigned int);

extern int __put_user_2(void *, unsigned int);

extern int __put_user_4(void *, unsigned int);

extern int __put_user_8(void *, unsigned long long);

extern int __put_user_bad(void);

#define __put_user_x(__r2,__p,__e,__s)     \

__asm__ __volatile__ (     \

__asmeq("%0", "r0") __asmeq("%2", "r2")   \

"bl __put_user_" #__s    \

: "=&r" (__e)      \

: "0" (__p), "r" (__r2)     \

: "ip", "lr", "cc")

#define put_user(x,p)       \

({        \

const register typeof(*(p)) __r2 asm("r2") = (x); \

const register typeof(*(p)) __user *__p asm("r0") = (p);\

register int __e asm("r0");    \

switch (sizeof(*(__p))) {    \

case 1:       \

__put_user_x(__r2, __p, __e, 1);  \

break;      \

case 2:       \

__put_user_x(__r2, __p, __e, 2);  \

break;      \

case 4:       \

__put_user_x(__r2, __p, __e, 4);  \

break;      \

case 8:       \

__put_user_x(__r2, __p, __e, 8);  \

break;      \

default: __e = __put_user_bad(); break;   \

}       \

__e;       \

})

__put_user_1等函数的的定义如下(linux/arch/arm/lib/putuser.S)。

.global __put_user_1

__put_user_1:

1: strbt r2, [r0]

mov r0, #0

mov pc, lr

.global __put_user_2

__put_user_2:

mov ip, r2, lsr #8

#ifndef __ARMEB__

2: strbt r2, [r0], #1

3: strbt ip, [r0]

#else

2: strbt ip, [r0], #1

3: strbt r2, [r0]

#endif

mov r0, #0

mov pc, lr

.global __put_user_4

__put_user_4:

4: strt r2, [r0]

mov r0, #0

mov pc, lr

.global __put_user_8

__put_user_8:

5: strt r2, [r0], #4

6: strt r3, [r0]

mov r0, #0

mov pc, lr

__put_user_bad:

mov r0, #-EFAULT

mov pc, lr

.section __ex_table, "a"

.long 1b, __put_user_bad

.long 2b, __put_user_bad

.long 3b, __put_user_bad

.long 4b, __put_user_bad

.long 5b, __put_user_bad

.long 6b, __put_user_bad

.previous

put_user函数就不具体分析了。get_user和put_user仅能完成一些简单类型变量的拷贝任务,后面我们将分析copy_to_user和copy_from_user。0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值