Chinese translated version of Documentation/arm/kernel_user_helpers.txt
If you have any comment or update to the content, please contact the
original document maintainer directly. However, if you have a problem
communicating in English you can also ask the Chinese maintainer for
help. Contact the Chinese maintainer if this translation is outdated
or if there is a problem with the translation.
Maintainer: Nicolas Pitre nicolas.pitre@linaro.org
Dave Martin dave.martin@linaro.org
Chinese maintainer: Fu Wei tekkamanninja@gmail.com
Documentation/arm/kernel_user_helpers.txt çä¸æç¿»è¯
å¦ææ³è¯è®ºææ´æ°æ¬æçå
容ï¼è¯·ç´æ¥èç³»åææ¡£çç»´æ¤è
ãå¦æä½ ä½¿ç¨è±æ
交æµæå°é¾çè¯ï¼ä¹å¯ä»¥åä¸æçç»´æ¤è
æ±å©ãå¦ææ¬ç¿»è¯æ´æ°ä¸åæ¶æè
ç¿»
è¯åå¨é®é¢ï¼è¯·èç³»ä¸æçç»´æ¤è
ã
è±æçç»´æ¤è
ï¼ Nicolas Pitre nicolas.pitre@linaro.org
Dave Martin dave.martin@linaro.org
ä¸æçç»´æ¤è
ï¼ å
ç Fu Wei tekkamanninja@gmail.com
ä¸æçç¿»è¯è
ï¼ å
ç Fu Wei tekkamanninja@gmail.com
ä¸æçæ ¡è¯è
ï¼ å®å¬ç Dongsheng Song dongshneg.song@gmail.com
å
ç Fu Wei tekkamanninja@gmail.com
以ä¸ä¸ºæ£æ
å æ ¸æä¾çç¨æ·ç©ºé´è¾ å©ä»£ç
å¨å
æ ¸å
å空é´çåºå®å°åå¤ï¼æä¸ä¸ªç±å
æ ¸æä¾å¹¶å¯ä»ç¨æ·ç©ºé´è®¿é®ç代ç
段ãå®ç¨äºåç¨æ·ç©ºé´æä¾å å¨è®¸å¤ ARM CPU ä¸æªå®ç°çç¹æ§å/ææ令èé
å
æ ¸æä¾å¸®å©çæäºæä½ãè¿äºä»£ç ç´æ¥å¨ç¨æ·æ¨¡å¼ä¸æ§è¡çæ³æ³æ¯ä¸ºäºè·å¾
æä½³æçï¼ä½é£äºä¸å
æ ¸è®¡æ°å¨èç³»è¿äºç´§å¯çé¨åï¼å被çç»äºç¨æ·åºå®ç°ã
äºå®ä¸ï¼æ¤ä»£ç çè³å¯è½å ä¸åç CPU èå¼ï¼è¿åå³äºå
¶å¯ç¨çæ令éæå®
æ¯å¦ä¸º SMP ç³»ç»ãæ¢å¥è¯è¯´ï¼å
æ ¸ä¿çå¨ä¸ä½åºè¦åçæ
åµä¸æ ¹æ®éè¦æ´æ¹
è¿äºä»£ç çæå©ãåªææ¬ææ¡£æè¿°çå
¥å£åå
¶ç»ææ¯ä¿è¯ç¨³å®çã
è¿ä¸å®å
¨æçç VDSO å®ç°ä¸åï¼ä½ä¸¤è
并ä¸å²çªï¼ï¼å°½ç®¡å¦æ¤ï¼VDSO å¯é»æ¢
æäºéè¿å¸¸éé«æ跳转å°é£äºä»£ç 段çæ±ç¼æå·§ãä¸ç±äºé£äºä»£ç 段å¨è¿åç¨æ·
代ç åä»
使ç¨å°éç代ç å¨æï¼åä¸ä¸ª VDSO é´æ¥è¿ç¨è°ç¨å°ä¼å¨è¿äºç®åç
æä½ä¸å¢å ä¸ä¸ªå¯æµéçå¼éã
å¨å¯¹é£äºæ¥æåçæ¯æçæ°åå¤çå¨è¿è¡ä»£ç ä¼åæ¶ï¼ä»
å¨å·²ä¸ºå
¶ä»æä½ä½¿ç¨
äºç±»ä¼¼çæ°å¢æ令ï¼è导è´äºè¿å¶ç»æå·²ä¸æ©æ ARM å¤çå¨ä¸å
¼å®¹çæ
åµä¸ï¼
ç¨æ·ç©ºé´æåºç»è¿è¿äºè¾
å©ä»£ç ï¼å¹¶å¨å
èå½æ°ä¸å®ç°è¿äºæä½ï¼æ 论æ¯éè¿
ç¼è¯å¨å¨ä»£ç ä¸ç´æ¥æ¾ç½®ï¼è¿æ¯ä½ä¸ºåºå½æ°è°ç¨å®ç°çä¸é¨åï¼ãä¹å°±æ¯è¯´ï¼
å¦æä½ ç¼è¯ç代ç ä¸ä¼ä¸ºäºå
¶ä»ç®ç使ç¨æ°æ令ï¼åä¸è¦ä»
为äºé¿å
使ç¨è¿äº
å
æ ¸è¾
å©ä»£ç ï¼å¯¼è´äºè¿å¶ç¨åºæ æ³å¨æ©æå¤çå¨ä¸è¿è¡ã
æ°çè¾
å©ä»£ç å¯è½éçæ¶é´çæ¨ç§»èå¢å ï¼æ以æ°å
æ ¸ä¸çæäºè¾
å©ä»£ç å¨æ§
å
æ ¸ä¸å¯è½ä¸åå¨ãå æ¤ï¼ç¨åºå¿
é¡»å¨å¯¹ä»»ä½è¾
å©ä»£ç è°ç¨å设æ¯å®å
¨ä¹åï¼
æ£æµ __kuser_helper_version çå¼ï¼è§ä¸æï¼ãçæ³æ
åµä¸ï¼è¿ç§æ£æµåºè¯¥
åªå¨è¿ç¨å¯å¨æ¶æ§è¡ä¸æ¬¡ï¼å¦æå
æ ¸çæ¬ä¸æ¯ææéè¾
å©ä»£ç ï¼å该è¿ç¨å¯å°½æ©
ä¸æ¢æ§è¡ã
kuser_helper_version
ä½ç½®: 0xffff0ffc
åè声æ:
extern int32_t __kuser_helper_version;
å®ä¹:
è¿ä¸ªåºåå
å«äºå½åè¿è¡å
æ ¸å®ç°çè¾
å©ä»£ç çæ¬å·ãç¨æ·ç©ºé´å¯ä»¥éè¿è¯»
åæ¤çæ¬å·ä»¥ç¡®å®ç¹å®çè¾
å©ä»£ç æ¯å¦åå¨ã
使ç¨èä¾:
#define __kuser_helper_version (*(int32_t *)0xffff0ffc)
void check_kuser_version(void)
{
if (__kuser_helper_version < 2) {
fprintf(stderr, “can’t do atomic operations, kernel too old\n”);
abort();
}
}
注æ:
ç¨æ·ç©ºé´å¯ä»¥å设è¿ä¸ªåçå¼ä¸ä¼å¨ä»»ä½å个è¿ç¨ççåæå
æ¹åãä¹å°±
æ¯è¯´ï¼è¿ä¸ªåå¯ä»¥ä»
å¨åºçåå§åé¶æ®µæè¿ç¨å¯å¨é¶æ®µè¯»åä¸æ¬¡ã
kuser_get_tls
ä½ç½®: 0xffff0fe0
åèåå:
void * __kuser_get_tls(void);
è¾å ¥:
lr = è¿åå°å
è¾åº:
r0 = TLS å¼
被篡æ¹çå¯åå¨:
æ
å®ä¹:
è·åä¹åéè¿ __ARM_NR_set_tls ç³»ç»è°ç¨è®¾ç½®ç TLS å¼ã
使ç¨èä¾:
typedef void * (__kuser_get_tls_t)(void);
#define __kuser_get_tls (*(__kuser_get_tls_t *)0xffff0fe0)
void foo()
{
void *tls = __kuser_get_tls();
printf(“TLS = %p\n”, tls);
}
注æ:
- ä»
å¨ __kuser_helper_version >= 1 æ¶ï¼æ¤è¾
å©ä»£ç åå¨
ï¼ä»å æ ¸çæ¬ 2.6.12 å¼å§ï¼ã
kuser_cmpxchg
ä½ç½®: 0xffff0fc0
åèåå:
int __kuser_cmpxchg(int32_t oldval, int32_t newval, volatile int32_t *ptr);
è¾å ¥:
r0 = oldval
r1 = newval
r2 = ptr
lr = è¿åå°å
è¾åº:
r0 = æå代ç (é¶æéé¶)
C flag = å¦æ r0 == 0 åç½® 1ï¼å¦æ r0 != 0 åæ¸
é¶ã
被篡æ¹çå¯åå¨:
r3, ip, flags
å®ä¹:
ä»
å¨ *ptr 为 oldval æ¶ååä¿å newval äº *ptr ä¸ã
å¦æ *ptr 被æ¹åï¼åè¿åå¼ä¸ºé¶ï¼å¦å为éé¶å¼ã
å¦æ *ptr 被æ¹åï¼å C flag ä¹ä¼è¢«ç½® 1ï¼ä»¥å®ç°è°ç¨ä»£ç ä¸çæ±ç¼
ä¼åã
使ç¨èä¾:
typedef int (__kuser_cmpxchg_t)(int oldval, int newval, volatile int ptr);
#define __kuser_cmpxchg ((__kuser_cmpxchg_t *)0xffff0fc0)
int atomic_add(volatile int *ptr, int val)
{
int old, new;
do {
old = *ptr;
new = old + val;
} while(__kuser_cmpxchg(old, new, ptr));
return new;
}
注æ:
è¿ä¸ªä¾ç¨å·²æ ¹æ®éè¦å å«äºå åå±éã
ä» å¨ __kuser_helper_version >= 2 æ¶ï¼æ¤è¾ å©ä»£ç åå¨
ï¼ä»å æ ¸çæ¬ 2.6.12 å¼å§ï¼ã
kuser_memory_barrier
ä½ç½®: 0xffff0fa0
åèåå:
void __kuser_memory_barrier(void);
è¾å ¥:
lr = è¿åå°å
è¾åº:
æ
被篡æ¹çå¯åå¨:
æ
å®ä¹:
åºç¨äºä»»ä½éè¦å
åå±é以é²æ¢æå¨æ°æ®ä¿®æ¹å¸¦æ¥çä¸è´æ§é®é¢ï¼ä»¥å
__kuser_cmpxchg ä¸ã
使ç¨èä¾:
typedef void (__kuser_dmb_t)(void);
#define __kuser_dmb (*(__kuser_dmb_t *)0xffff0fa0)
注æ:
- ä»
å¨ __kuser_helper_version >= 3 æ¶ï¼æ¤è¾
å©ä»£ç åå¨
ï¼ä»å æ ¸çæ¬ 2.6.15 å¼å§ï¼ã
kuser_cmpxchg64
ä½ç½®: 0xffff0f60
åèåå:
int __kuser_cmpxchg64(const int64_t *oldval,
const int64_t *newval,
volatile int64_t *ptr);
è¾å ¥:
r0 = æå oldval
r1 = æå newval
r2 = æåç®æ å¼
lr = è¿åå°å
è¾åº:
r0 = æå代ç (é¶æéé¶)
C flag = å¦æ r0 == 0 åç½® 1ï¼å¦æ r0 != 0 åæ¸
é¶ã
被篡æ¹çå¯åå¨:
r3, lr, flags
å®ä¹:
ä»
å¨ *ptr çäº *oldval æåç 64 ä½å¼æ¶ï¼ååä¿å *newval
æåç 64 ä½å¼äº *ptr ä¸ãå¦æ *ptr 被æ¹åï¼åè¿åå¼ä¸ºé¶ï¼
å¦å为éé¶å¼ã
å¦æ *ptr 被æ¹åï¼å C flag ä¹ä¼è¢«ç½® 1ï¼ä»¥å®ç°è°ç¨ä»£ç ä¸çæ±ç¼
ä¼åã
使ç¨èä¾:
typedef int (__kuser_cmpxchg64_t)(const int64_t oldval,
const int64_t *newval,
volatile int64_t *ptr);
#define __kuser_cmpxchg64 ((__kuser_cmpxchg64_t *)0xffff0f60)
int64_t atomic_add64(volatile int64_t *ptr, int64_t val)
{
int64_t old, new;
do {
old = *ptr;
new = old + val;
} while(__kuser_cmpxchg64(&old, &new, ptr));
return new;
}
注æ:
è¿ä¸ªä¾ç¨å·²æ ¹æ®éè¦å å«äºå åå±éã
ç±äºè¿ä¸ªè¿ç¨ç代ç é¿åº¦ï¼æ¤è¾ å©ä»£ç è·¨è¶ 2 个常è§ç kuser â槽âï¼ï¼
å æ¤ 0xffff0f80 ä¸è¢«ä½ä¸ºææçå ¥å£ç¹ãä» å¨ __kuser_helper_version >= 5 æ¶ï¼æ¤è¾ å©ä»£ç åå¨
ï¼ä»å æ ¸çæ¬ 3.1 å¼å§ï¼ã