~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/Documentation/translations/zh_TW/arch/arm/kernel_user_helpers.txt

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 Chinese translated version of Documentation/arch/arm/kernel_user_helpers.rst
  2 
  3 If you have any comment or update to the content, please contact the
  4 original document maintainer directly.  However, if you have a problem
  5 communicating in English you can also ask the Chinese maintainer for
  6 help.  Contact the Chinese maintainer if this translation is outdated
  7 or if there is a problem with the translation.
  8 
  9 Maintainer: Nicolas Pitre <nicolas.pitre@linaro.org>
 10                 Dave Martin <dave.martin@linaro.org>
 11 Chinese maintainer: Fu Wei <tekkamanninja@gmail.com>
 12 ---------------------------------------------------------------------
 13 Documentation/arch/arm/kernel_user_helpers.rst 的中文翻譯
 14 
 15 如果想評論或更新本文的內容,請直接聯繫原文檔的維護者。如果你使用英文
 16 交流有困難的話,也可以向中文版維護者求助。如果本翻譯更新不及時或者翻
 17 譯存在問題,請聯繫中文版維護者。
 18 英文版維護者: Nicolas Pitre <nicolas.pitre@linaro.org>
 19                 Dave Martin <dave.martin@linaro.org>
 20 中文版維護者: 傅煒 Fu Wei <tekkamanninja@gmail.com>
 21 中文版翻譯者: 傅煒 Fu Wei <tekkamanninja@gmail.com>
 22 中文版校譯者: 宋冬生 Dongsheng Song <dongshneg.song@gmail.com>
 23                 傅煒 Fu Wei <tekkamanninja@gmail.com>
 24 
 25 
 26 以下爲正文
 27 ---------------------------------------------------------------------
 28 內核提供的用戶空間輔助代碼
 29 =========================
 30 
 31 在內核內存空間的固定地址處,有一個由內核提供並可從用戶空間訪問的代碼
 32 段。它用於向用戶空間提供因在許多 ARM CPU 中未實現的特性和/或指令而需
 33 內核提供幫助的某些操作。這些代碼直接在用戶模式下執行的想法是爲了獲得
 34 最佳效率,但那些與內核計數器聯繫過於緊密的部分,則被留給了用戶庫實現。
 35 事實上,此代碼甚至可能因不同的 CPU 而異,這取決於其可用的指令集或它
 36 是否爲 SMP 系統。換句話說,內核保留在不作出警告的情況下根據需要更改
 37 這些代碼的權利。只有本文檔描述的入口及其結果是保證穩定的。
 38 
 39 這與完全成熟的 VDSO 實現不同(但兩者並不衝突),儘管如此,VDSO 可阻止
 40 某些通過常量高效跳轉到那些代碼段的彙編技巧。且由於那些代碼段在返回用戶
 41 代碼前僅使用少量的代碼週期,則一個 VDSO 間接遠程調用將會在這些簡單的
 42 操作上增加一個可測量的開銷。
 43 
 44 在對那些擁有原生支持的新型處理器進行代碼優化時,僅在已爲其他操作使用
 45 了類似的新增指令,而導致二進制結果已與早期 ARM 處理器不兼容的情況下,
 46 用戶空間才應繞過這些輔助代碼,並在內聯函數中實現這些操作(無論是通過
 47 編譯器在代碼中直接放置,還是作爲庫函數調用實現的一部分)。也就是說,
 48 如果你編譯的代碼不會爲了其他目的使用新指令,則不要僅爲了避免使用這些
 49 內核輔助代碼,導致二進制程序無法在早期處理器上運行。
 50 
 51 新的輔助代碼可能隨着時間的推移而增加,所以新內核中的某些輔助代碼在舊
 52 內核中可能不存在。因此,程序必須在對任何輔助代碼調用假設是安全之前,
 53 檢測 __kuser_helper_version 的值(見下文)。理想情況下,這種檢測應該
 54 只在進程啓動時執行一次;如果內核版本不支持所需輔助代碼,則該進程可儘早
 55 中止執行。
 56 
 57 kuser_helper_version
 58 --------------------
 59 
 60 位置: 0xffff0ffc
 61 
 62 參考聲明:
 63 
 64   extern int32_t __kuser_helper_version;
 65 
 66 定義:
 67 
 68   這個區域包含了當前運行內核實現的輔助代碼版本號。用戶空間可以通過讀
 69   取此版本號以確定特定的輔助代碼是否存在。
 70 
 71 使用範例:
 72 
 73 #define __kuser_helper_version (*(int32_t *)0xffff0ffc)
 74 
 75 void check_kuser_version(void)
 76 {
 77         if (__kuser_helper_version < 2) {
 78                 fprintf(stderr, "can't do atomic operations, kernel too old\n");
 79                 abort();
 80         }
 81 }
 82 
 83 注意:
 84 
 85   用戶空間可以假設這個域的值不會在任何單個進程的生存期內改變。也就
 86   是說,這個域可以僅在庫的初始化階段或進程啓動階段讀取一次。
 87 
 88 kuser_get_tls
 89 -------------
 90 
 91 位置: 0xffff0fe0
 92 
 93 參考原型:
 94 
 95   void * __kuser_get_tls(void);
 96 
 97 輸入:
 98 
 99   lr = 返回地址
100 
101 輸出:
102 
103   r0 = TLS 值
104 
105 被篡改的寄存器:
106 
107108 
109 定義:
110 
111   獲取之前通過 __ARM_NR_set_tls 系統調用設置的 TLS 值。
112 
113 使用範例:
114 
115 typedef void * (__kuser_get_tls_t)(void);
116 #define __kuser_get_tls (*(__kuser_get_tls_t *)0xffff0fe0)
117 
118 void foo()
119 {
120         void *tls = __kuser_get_tls();
121         printf("TLS = %p\n", tls);
122 }
123 
124 注意:
125 
126   - 僅在 __kuser_helper_version >= 1 時,此輔助代碼存在
127     (從內核版本 2.6.12 開始)。
128 
129 kuser_cmpxchg
130 -------------
131 
132 位置: 0xffff0fc0
133 
134 參考原型:
135 
136   int __kuser_cmpxchg(int32_t oldval, int32_t newval, volatile int32_t *ptr);
137 
138 輸入:
139 
140   r0 = oldval
141   r1 = newval
142   r2 = ptr
143   lr = 返回地址
144 
145 輸出:
146 
147   r0 = 成功代碼 (零或非零)
148   C flag = 如果 r0 == 0 則置 1,如果 r0 != 0 則清零。
149 
150 被篡改的寄存器:
151 
152   r3, ip, flags
153 
154 定義:
155 
156   僅在 *ptr 爲 oldval 時原子保存 newval 於 *ptr 中。
157   如果 *ptr 被改變,則返回值爲零,否則爲非零值。
158   如果 *ptr 被改變,則 C flag 也會被置 1,以實現調用代碼中的彙編
159   優化。
160 
161 使用範例:
162 
163 typedef int (__kuser_cmpxchg_t)(int oldval, int newval, volatile int *ptr);
164 #define __kuser_cmpxchg (*(__kuser_cmpxchg_t *)0xffff0fc0)
165 
166 int atomic_add(volatile int *ptr, int val)
167 {
168         int old, new;
169 
170         do {
171                 old = *ptr;
172                 new = old + val;
173         } while(__kuser_cmpxchg(old, new, ptr));
174 
175         return new;
176 }
177 
178 注意:
179 
180   - 這個例程已根據需要包含了內存屏障。
181 
182   - 僅在 __kuser_helper_version >= 2 時,此輔助代碼存在
183     (從內核版本 2.6.12 開始)。
184 
185 kuser_memory_barrier
186 --------------------
187 
188 位置: 0xffff0fa0
189 
190 參考原型:
191 
192   void __kuser_memory_barrier(void);
193 
194 輸入:
195 
196   lr = 返回地址
197 
198 輸出:
199 
200201 
202 被篡改的寄存器:
203 
204205 
206 定義:
207 
208   應用於任何需要內存屏障以防止手動數據修改帶來的一致性問題,以及
209   __kuser_cmpxchg 中。
210 
211 使用範例:
212 
213 typedef void (__kuser_dmb_t)(void);
214 #define __kuser_dmb (*(__kuser_dmb_t *)0xffff0fa0)
215 
216 注意:
217 
218   - 僅在 __kuser_helper_version >= 3 時,此輔助代碼存在
219     (從內核版本 2.6.15 開始)。
220 
221 kuser_cmpxchg64
222 ---------------
223 
224 位置: 0xffff0f60
225 
226 參考原型:
227 
228   int __kuser_cmpxchg64(const int64_t *oldval,
229                         const int64_t *newval,
230                         volatile int64_t *ptr);
231 
232 輸入:
233 
234   r0 = 指向 oldval
235   r1 = 指向 newval
236   r2 = 指向目標值
237   lr = 返回地址
238 
239 輸出:
240 
241   r0 = 成功代碼 (零或非零)
242   C flag = 如果 r0 == 0 則置 1,如果 r0 != 0 則清零。
243 
244 被篡改的寄存器:
245 
246   r3, lr, flags
247 
248 定義:
249 
250   僅在 *ptr 等於 *oldval 指向的 64 位值時,原子保存 *newval
251   指向的 64 位值於 *ptr 中。如果 *ptr 被改變,則返回值爲零,
252   否則爲非零值。
253 
254   如果 *ptr 被改變,則 C flag 也會被置 1,以實現調用代碼中的彙編
255   優化。
256 
257 使用範例:
258 
259 typedef int (__kuser_cmpxchg64_t)(const int64_t *oldval,
260                                   const int64_t *newval,
261                                   volatile int64_t *ptr);
262 #define __kuser_cmpxchg64 (*(__kuser_cmpxchg64_t *)0xffff0f60)
263 
264 int64_t atomic_add64(volatile int64_t *ptr, int64_t val)
265 {
266         int64_t old, new;
267 
268         do {
269                 old = *ptr;
270                 new = old + val;
271         } while(__kuser_cmpxchg64(&old, &new, ptr));
272 
273         return new;
274 }
275 
276 注意:
277 
278   - 這個例程已根據需要包含了內存屏障。
279 
280   - 由於這個過程的代碼長度(此輔助代碼跨越 2 個常規的 kuser “槽”),
281     因此 0xffff0f80 不被作爲有效的入口點。
282 
283   - 僅在 __kuser_helper_version >= 5 時,此輔助代碼存在
284     (從內核版本 3.1 開始)。
285 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php