Chinese translated version of Documentation/arm/kernel_user_helpers.rst 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.rst çä¸æç¿»è¯ å¦ææ³è¯è®ºææ´æ°æ¬æçå 容ï¼è¯·ç´æ¥èç³»åææ¡£çç»´æ¤è ãå¦æä½ ä½¿ç¨è±æ 交æµæå°é¾çè¯ï¼ä¹å¯ä»¥åä¸æçç»´æ¤è æ±å©ãå¦ææ¬ç¿»è¯æ´æ°ä¸åæ¶æè ç¿» è¯åå¨é®é¢ï¼è¯·èç³»ä¸æçç»´æ¤è ã è±æçç»´æ¤è ï¼ 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 å¼å§ï¼ã