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

TOMOYO Linux Cross Reference
Linux/Documentation/translations/zh_CN/kernel-hacking/hacking.rst

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 ] ~

Diff markup

Differences between /Documentation/translations/zh_CN/kernel-hacking/hacking.rst (Version linux-6.12-rc7) and /Documentation/translations/zh_CN/kernel-hacking/hacking.rst (Version linux-5.6.19)


  1 .. include:: ../disclaimer-zh_CN.rst              
  2                                                   
  3 :Original: Documentation/kernel-hacking/hackin    
  4                                                   
  5 :译者:                                          
  6                                                   
  7  吴想成 Wu XiangCheng <bobwxc@email.cn>         
  8                                                   
  9 ==============                                    
 10 内核骇客指北                                
 11 ==============                                    
 12                                                   
 13 :作者: Rusty Russell                            
 14                                                   
 15 引言                                            
 16 =====                                             
 17                                                   
 18 欢迎咱优雅的读者们来阅读Rusty的    
 19 描述了内核代码的常见例程和一般    
 20 开发。我回避了实现细节:这是代    
 21                                                   
 22 在你读这篇文章之前,请理解我从    
 23 但我一直想读这样的文章,自己写    
 24 通用起点和其他信息的汇编。           
 25                                                   
 26 玩家                                            
 27 =======                                           
 28                                                   
 29 在任何时候,系统中的每个CPU都可    
 30                                                   
 31 -  与任何进程无关,服务于硬件中    
 32                                                   
 33 -  与任何进程无关,服务于软件中    
 34                                                   
 35 -  运行于内核空间中,与进程(用    
 36                                                   
 37 -  在用户空间中运行进程。              
 38                                                   
 39 它们之间有优先级顺序。最下面的    
 40 每个层级只能被上方的抢占。例如    
 41 会抢占它,但是硬件中断可以抢占    
 42                                                   
 43 我们将会看到许多方法,用户上下    
 44                                                   
 45 用户上下文                                   
 46 ------------                                      
 47                                                   
 48 用户上下文是指当您从系统调用或    
 49 重要的任务和中断抢占。您可以通    
 50                                                   
 51 .. note::                                         
 52                                                   
 53     在模块加载和卸载以及块设备层    
 54                                                   
 55 在用户上下文中,当前 ``current`` 指    
 56 且 :c:func:`in_interrupt()` ( ``include/lin    
 57                                                   
 58 .. warning::                                      
 59                                                   
 60     请注意,如果您禁用了抢占或软    
 61     返回假阳性。                            
 62                                                   
 63 硬件中断(Hard IRQs)                       
 64 ----------------------                            
 65                                                   
 66 像定时器、网卡和键盘等都是可能    
 67 处理程序,为硬件提供服务。内核    
 68 它将被排队(或丢弃)。因为它会    
 69 确认中断,标记一个“软件中断”    
 70                                                   
 71 您可以通过 in_hardirq() 返回真来判    
 72                                                   
 73 .. warning::                                      
 74                                                   
 75     请注意,如果中断被禁用,这将    
 76                                                   
 77 软件中断上下文:软中断(Softirqs    
 78 ----------------------------------------------    
 79                                                   
 80 当系统调用即将返回用户空间或硬    
 81 过硬件中断)的“软件中断”将运    
 82                                                   
 83 此处完成了许多真正的中断处理工    
 84 部”(BHs)机制,无法利用多个CPU    
 85 我们放弃了这个限制,转而使用“    
 86                                                   
 87 ``include/linux/interrupt.h`` 列出了不同    
 88 的软中断( ``include/linux/timer.h`` )    
 89 函数。                                         
 90                                                   
 91 软中断通常是一个很难处理的问题    
 92 子任务( ``include/linux/interrupt.h`` )    
 93 您可以拥有任意数量),并且它们    
 94 子任务也可以同时运行。                 
 95                                                   
 96 .. warning::                                      
 97                                                   
 98     “tasklet”这个名字是误导性的    
 99                                                   
100 你可以使用 :c:func:`in_softirq()` 宏(     
101 是否处于软中断(或子任务)中。     
102                                                   
103 .. warning::                                      
104                                                   
105     注意,如果持有 :ref:`bottom half lo    
106     假阳性。                                  
107                                                   
108 一些基本规则                                
109 ================                                  
110                                                   
111 缺少内存保护                                
112     如果你损坏了内存,无论是在用    
113     你确定你不能在用户空间里做你    
114                                                   
115 缺少浮点或MMX                                
116     FPU上下文不会被保存;即使在用    
117     您会弄乱某些用户进程的FPU状态    
118     完整的FPU状态(并避免上下文切    
119                                                   
120 严格的堆栈限制                             
121     对于大多数32位体系结构,根据    
122     多数64位机器,内核堆栈大约为1    
123     应避免深度递归和栈上的巨型本    
124                                                   
125 Linux内核是可移植的                        
126     就这样吧。您的代码应该是纯64    
127     尽量减少CPU特定的东西,例如内    
128     最小化以便于移植。一般来说,    
129                                                   
130 输入输出控制(ioctls):避免编写    
131 ==============================================    
132                                                   
133 系统调用(system call)通常看起来    
134                                                   
135     asmlinkage long sys_mycall(int arg)           
136     {                                             
137             return 0;                             
138     }                                             
139                                                   
140                                                   
141 首先,在大多数情况下,您无需创    
142 的输入输出控制(ioctls)。这比系    
143 ``include/asm/unistd.h`` 和 ``arch/kernel/ent    
144 接受。                                         
145                                                   
146 如果您的程序所做的只是读取或写    
147                                                   
148 在输入输出控制中,您处于进程的    
149 (errno,请参阅 ``include/uapi/asm-generi    
150 ``include/uapi/asm-generic/errno.h`` 和 ``inc    
151 回0。                                           
152                                                   
153 在睡眠之后,您应该检查是否出现    
154 调用,并返回 ``-ERESTARTSYS`` 错误。    
155 信号处理程序,然后系统调用将重    
156 备好处理重新启动,例如若您处理    
157                                                   
158 ::                                                
159                                                   
160     if (signal_pending(current))                  
161             return -ERESTARTSYS;                  
162                                                   
163                                                   
164 如果你要做更长时间的计算:优先    
165 应该定期检查你是否需要让出CPU(    
166 习惯用法::                                    
167                                                   
168     cond_resched(); /* Will sleep */              
169                                                   
170                                                   
171 接口设计的小注释:UNIX系统调用的    
172 Provide mechanism not policy”。                
173                                                   
174 死锁的“配方”                             
175 ====================                              
176                                                   
177 您不能调用任何可能睡眠的程序,    
178                                                   
179 - 您处于用户上下文中。                  
180                                                   
181 - 你未拥有任何自旋锁。                  
182                                                   
183 - 您已经启用中断(实际上,Andi Kle    
184   您想要的)。                              
185                                                   
186 注意,有些函数可能隐式地睡眠:    
187 ``GFP_ATOMIC`` 的内存分配函数。           
188                                                   
189 您应该始终打开  ``CONFIG_DEBUG_ATOMIC_S    
190 规则,它将警告您。如果你 **真的*    
191                                                   
192 真的会这样。                                
193                                                   
194                                                   
195 常用函数/程序                               
196 ===============                                   
197                                                   
198 :c:func:`printk()`                                
199 ------------------                                
200                                                   
201 定义于 ``include/linux/printk.h``              
202                                                   
203 :c:func:`printk()` 将内核消息提供给控    
204 试和报告错误很有用,并且可以在    
205 的控制台中充斥着printk消息则会无    
206 字符串,并通过C字符串串联为其提    
207                                                   
208     printk(KERN_INFO "i = %u\n", i);              
209                                                   
210                                                   
211 参见 ``include/linux/kern_levels.h`` ;了    
212 解释为级别。特殊用法:打印IP地    
213                                                   
214     __be32 ipaddress;                             
215     printk(KERN_INFO "my ip: %pI4\n", &ipaddre    
216                                                   
217                                                   
218 :c:func:`printk()` 内部使用的1K缓冲区    
219                                                   
220 .. note::                                         
221                                                   
222     当您开始在用户程序中将printf打    
223     :)                                            
224                                                   
225 .. note::                                         
226                                                   
227     另一个注释:最初的unix第六版    
228     不应该用于叽叽喳喳”。你也应    
229                                                   
230 :c:func:`copy_to_user()` / :c:func:`copy_from_    
231 ----------------------------------------------    
232                                                   
233 定义于 ``include/linux/uaccess.h`` / ``asm/    
234                                                   
235 **[睡眠]**                                      
236                                                   
237 :c:func:`put_user()` 和 :c:func:`get_user()`     
238 间中传出单个值(如int、char或long    
239 引用:应该使用这些程序复制数据    
240                                                   
241 :c:func:`copy_to_user()` 和 :c:func:`copy_fro    
242 空间复制任意数量的数据。              
243                                                   
244 .. warning::                                      
245                                                   
246     与 :c:func:`put_user()` 和 :c:func:`get_    
247     数据量(即0仍然意味着成功)    
248                                                   
249 【是的,这个讨厌的接口真心让我    
250 —— Rusty Russell】                           
251                                                   
252 这些函数可以隐式睡眠。它不应该    
253 或获得自旋锁。                             
254                                                   
255 :c:func:`kmalloc()`/:c:func:`kfree()`             
256 -------------------------------------             
257                                                   
258 定义于 ``include/linux/slab.h``                
259                                                   
260 **[可能睡眠:见下]**                       
261                                                   
262 这些函数用于动态请求指针对齐的    
263 :c:func:`kmalloc()` 需要额外的标志词    
264                                                   
265 ``GFP_KERNEL``                                    
266     可以睡眠和交换以释放内存。只    
267     的方法。                                  
268                                                   
269 ``GFP_ATOMIC``                                    
270     不会睡眠。较 ``GFP_KERNEL`` 更不    
271     有一个很好的内存不足错误处理    
272                                                   
273 ``GFP_DMA``                                       
274     分配低于16MB的ISA DMA。如果你不    
275                                                   
276 如果您看到一个从无效上下文警告    
277 ``GFP_ATOMIC`` 的情况下从中断上下文    
278 快点!                                         
279                                                   
280 如果你要分配至少 ``PAGE_SIZE`` ( ``a    
281 字节,请考虑使用 :c:func:`__get_free_p    
282 它采用顺序参数(0表示页面大小,    
283 优先级标志字。                             
284                                                   
285 如果分配的字节数超过一页,可以    
286 配虚拟内存。此块在物理内存中不    
287 是为您准备好的连续空间(因此它    
288 如果您真的需要为一些奇怪的设备    
289 Linux对此支持很差,因为正在运行    
290 方法是在引导过程的早期通过 :c:fun    
291                                                   
292 在创建自己的常用对象缓存之前,    
293 缓存。                                         
294                                                   
295 :c:macro:`current`                                
296 ------------------                                
297                                                   
298 定义于 ``include/asm/current.h``               
299                                                   
300 此全局变量(其实是宏)包含指向    
301 用户上下文中有效。例如,当进程    
302 在中断上下文中不为空(**not NULL**    
303                                                   
304 :c:func:`mdelay()`/:c:func:`udelay()`             
305 -------------------------------------             
306                                                   
307 定义于 ``include/asm/delay.h`` / ``include/    
308                                                   
309 :c:func:`udelay()` 和 :c:func:`ndelay()` 函    
310 大的值,因为这样会导致溢出——    
311 考虑 :c:func:`msleep()`。                      
312                                                   
313 :c:func:`cpu_to_be32()`/:c:func:`be32_to_cpu()    
314 ----------------------------------------------    
315                                                   
316 定义于 ``include/asm/byteorder.h``             
317                                                   
318 :c:func:`cpu_to_be32()` 系列函数(其中    
319 “le”)是在内核中进行字节序转    
320 提供反向转换函数:                       
321 :c:func:`be32_to_cpu()` 等。                    
322                                                   
323 这些函数有两个主要的变体:指针    
324 指向给定类型的指针,并返回转换    
325 :c:func:`cpu_to_be32s()` ,它转换指针引    
326                                                   
327 :c:func:`local_irq_save()`/:c:func:`local_irq_    
328 ----------------------------------------------    
329                                                   
330 定义于 ``include/linux/irqflags.h``            
331                                                   
332                                                   
333 这些程序禁用本地CPU上的硬中断,    
334 ``unsigned long flags`` 参数中保存以前    
335 直接使用 :c:func:`local_irq_disable()` 和    
336                                                   
337 .. _local_bh_disable_zh:                          
338                                                   
339 :c:func:`local_bh_disable()`/:c:func:`local_bh    
340 ----------------------------------------------    
341                                                   
342 定义于 ``include/linux/bottom_half.h``         
343                                                   
344                                                   
345 这些程序禁用本地CPU上的软中断,    
346 软中断,那么在调用这对函数之后    
347 CPU上运行。                                   
348                                                   
349 :c:func:`smp_processor_id()`                      
350 ----------------------------                      
351                                                   
352 定义于 ``include/linux/smp.h``                 
353                                                   
354 :c:func:`get_cpu()` 禁用抢占(这样您    
355 处理器号,介于0和 ``NR_CPUS`` 之间    
356 使用 :c:func:`put_cpu()` 再次返回。        
357                                                   
358 如果您知道您不能被另一个任务抢    
359 可以使用 :c:func:`smp_processor_id()`。      
360                                                   
361 ``__init``/``__exit``/``__initdata``              
362 ------------------------------------              
363                                                   
364 定义于  ``include/linux/init.h``               
365                                                   
366 引导之后,内核释放一个特殊的部    
367 标记的数据结构在引导完成后被丢    
368 ``__exit`` 用于声明只在退出时需要    
369 被删除。请参阅头文件以使用。请    
370 :c:func:`EXPORT_SYMBOL_GPL()` 将标记为 ``_    
371 的——这将出问题。                       
372                                                   
373                                                   
374 :c:func:`__initcall()`/:c:func:`module_init()`    
375 ----------------------------------------------    
376                                                   
377 定义于  ``include/linux/init.h`` / ``includ    
378                                                   
379 内核的许多部分都作为模块(内核    
380 :c:func:`module_init()` 和 :c:func:`module_ex    
381 ``#ifdef`` ,即可以作为模块运行或    
382                                                   
383 :c:func:`module_init()` 宏定义在模块插    
384 调用哪个函数:如果文件未编译为    
385 :c:func:`__initcall()` ,它通过链接器    
386                                                   
387 该函数可以返回一个错误值,以导    
388 中,则此操作无效)。此函数在启    
389                                                   
390 :c:func:`module_exit()`                           
391 -----------------------                           
392                                                   
393                                                   
394 定义于  ``include/linux/module.h``             
395                                                   
396 这个宏定义了在模块删除时要调用    
397 只有在模块使用计数到零时才会调    
398 时,所有的东西都必须清理干净。     
399                                                   
400 注意,这个宏是可选的:如果它不    
401                                                   
402 :c:func:`try_module_get()`/:c:func:`module_put    
403 ----------------------------------------------    
404                                                   
405 定义于 ``include/linux/module.h``              
406                                                   
407 这些函数会操作模块使用计数,以    
408 则无法删除模块,参见下文)。在    
409 :c:func:`try_module_get()` :若失败,那    
410 若成功,您就可以安全地进入模块    
411                                                   
412 大多数可注册结构体都有所有者字    
413 :c:type:`struct file_operations <file_operatio    
414 宏 ``THIS_MODULE`` 。                           
415                                                   
416 等待队列 ``include/linux/wait.h``             
417 ====================================              
418                                                   
419 **[睡眠]**                                      
420                                                   
421 等待队列用于等待某程序在条件为    
422 条件。先声明一个 :c:type:`wait_queue_h    
423 一个关于它们自己的 :c:type:`wait_queu    
424                                                   
425 声明                                            
426 -----                                             
427                                                   
428 使用 :c:func:`DECLARE_WAIT_QUEUE_HEAD()` 宏    
429 或者在初始化代码中使用 :c:func:`ini    
430                                                   
431 排队                                            
432 -----                                             
433                                                   
434 将自己放在等待队列中相当复杂,    
435 个宏可以来执行此操作: :c:func:`wai    
436 ( ``include/linux/wait.h`` )第一个参    
437 式;当该表达式为true时宏返回0,    
438 :c:func:`wait_event()` 版本会忽略信号    
439                                                   
440 唤醒排队任务                                
441 -------------                                     
442                                                   
443 调用 :c:func:`wake_up()` ( ``include/linux    
444 进程。例外情况:如果有一个进程    
445 会被唤醒。这个基本函数的其他变    
446                                                   
447 原子操作                                      
448 =========                                         
449                                                   
450 某些操作在所有平台上都有保证。    
451 ( ``include/asm/atomic.h`` )的函数;    
452 您必须使用这些函数来操作或读取     
453 :c:func:`atomic_read()` 和 :c:func:`atomic_se    
454 :c:func:`atomic_add()` ,:c:func:`atomic_sub(    
455 :c:func:`atomic_dec()` 和 :c:func:`atomic_dec    
456 则返回true)。                               
457                                                   
458 是的。它在原子变量为零时返回true    
459                                                   
460 请注意,这些函数比普通的算术运    
461                                                   
462 第二类原子操作是在 ``unsigned long``     
463 原子位操作。这些操作通常采用指    
464 位。:c:func:`set_bit()`,:c:func:`clear_bit    
465 清除和更改给定位。:c:func:`test_and_s    
466 和 :c:func:`test_and_change_bit()` 执行相    
467 true;这些对于原子设置标志特别有    
468                                                   
469 可以使用大于 ``BITS_PER_LONG`` 位的位    
470 不太正常,所以最好不要这样做。     
471                                                   
472 符号                                            
473 =====                                             
474                                                   
475 在内核内部,正常的链接规则仍然    
476 否则它可以在内核中的任何位置使    
477 该表将入口点限制为内核内部。模    
478                                                   
479 :c:func:`EXPORT_SYMBOL()`                         
480 -------------------------                         
481                                                   
482 定义于 ``include/linux/export.h``              
483                                                   
484 这是导出符号的经典方法:动态加    
485                                                   
486 :c:func:`EXPORT_SYMBOL_GPL()`                     
487 -----------------------------                     
488                                                   
489 定义于 ``include/linux/export.h``              
490                                                   
491                                                   
492 类似于 :c:func:`EXPORT_SYMBOL()`,只是 :    
493 符号只能由具有由 :c:func:`MODULE_LICEN    
494 意味着此函数被认为是一个内部实    
495 开发人员在添加一些新的API或功能    
496                                                   
497 :c:func:`EXPORT_SYMBOL_NS()`                      
498 ----------------------------                      
499                                                   
500 定义于 ``include/linux/export.h``              
501                                                   
502 这是 ``EXPORT_SYMBOL()`` 的变体,允许    
503 Documentation/core-api/symbol-namespaces.rst     
504                                                   
505 :c:func:`EXPORT_SYMBOL_NS_GPL()`                  
506 --------------------------------                  
507                                                   
508 定义于 ``include/linux/export.h``              
509                                                   
510 这是 ``EXPORT_SYMBOL_GPL()`` 的变体,允    
511 Documentation/core-api/symbol-namespaces.rst     
512                                                   
513 程序与惯例                                   
514 ===========                                       
515                                                   
516 双向链表 ``include/linux/list.h``             
517 -----------------------------------               
518                                                   
519 内核头文件中曾经有三组链表程序    
520 需求,那么这是一个不错的选择。     
521                                                   
522 通常 :c:func:`list_for_each_entry()` 很有    
523                                                   
524 返回值惯例                                   
525 ------------                                      
526                                                   
527 对于在用户上下文中调用的代码,    
528 负错误值(例如 ``-EFAULT`` )表示失    
529 相当普遍。                                   
530                                                   
531 使用 :c:func:`ERR_PTR()` ( ``include/linux    
532 然后使用 :c:func:`IS_ERR()` 和 :c:func:`P    
533 使用单独的指针参数。挺讨厌的,    
534                                                   
535 破坏编译                                      
536 ----------                                        
537                                                   
538 Linus和其他开发人员有时会更改开    
539 让每个人都保持警惕,还反映了一    
540 调用,或者执行额外的检查,或者    
541 相当全面的注释到相应的内核邮件    
542 替换通常只会让事情变得 **更糟**     
543                                                   
544 初始化结构体成员                          
545 ------------------                                
546                                                   
547 初始化结构体的首选方法是使用指    
548 例如::                                          
549                                                   
550     static struct block_device_operations opt_    
551             .open               = opt_open,       
552             .release            = opt_release,    
553             .ioctl              = opt_ioctl,      
554             .check_media_change = opt_media_ch    
555     };                                            
556                                                   
557                                                   
558 这使得很容易查找(grep),并且可    
559 因为它看起来很酷。                       
560                                                   
561 GNU 扩展                                        
562 ----------                                        
563                                                   
564 Linux内核中明确允许GNU扩展。请注    
565 得到很好的支持,但以下内容被认    
566 的“C 扩展”部分——是的,实际    
567                                                   
568 - 内联函数                                    
569                                                   
570 - 语句表达式(Statement expressions)    
571                                                   
572                                                   
573 - 声明函数/变量/类型的属性(__attr    
574                                                   
575 - typeof                                          
576                                                   
577 - 零长度数组                                 
578                                                   
579 - 宏变量                                       
580                                                   
581 - 空指针运算                                 
582                                                   
583 - 非常量(Non-Constant)初始化程序      
584                                                   
585 - 汇编程序指令(在 arch/ 和 include/a    
586                                                   
587 - 字符串函数名(__func__)。             
588                                                   
589 - __builtin_constant_p()                          
590                                                   
591 在内核中使用long long时要小心,gcc    
592 不能工作,因为内核环境中缺少用    
593                                                   
594 C++                                               
595 ---                                               
596                                                   
597 在内核中使用C++通常是个坏主意,    
598 测试包含文件。不过这仍然是可能    
599 异常处理(exceptions)。                   
600                                                   
601 #if                                               
602 ---                                               
603                                                   
604 通常认为,在头文件(或.c文件顶    
605 处理器语句更干净。                       
606                                                   
607 把你的东西放进内核里                    
608 ======================                            
609                                                   
610 为了让你的东西更正式、补丁更整    
611                                                   
612 -  搞清楚你修改的代码属于谁。查    
613    ``CREDITS`` 文件的最后一部分。你    
614    或者尝试一些已经被拒绝的东西    
615                                                   
616    确保你把你的名字和电子邮件地    
617    现一个缺陷,或者想要做出修改    
618                                                   
619 -  通常你需要一个配置选项来支持    
620    配置语言很容易通过剪切和粘贴    
621    Documentation/kbuild/kconfig-language.rst     
622                                                   
623    在您对选项的描述中,请确保同    
624    在此说明任何不兼容和问题。结    
625    这是针对那些看不懂你在说什么    
626                                                   
627 -  编辑 ``Makefile`` :配置变量在这    
628    “obj-$(CONFIG_xxx) += xxx.o”。语法    
629    Documentation/kbuild/makefiles.rst 。         
630                                                   
631 -  如果你认为自己做了一些有意义    
632    止一个文件(无论如何你的名字    
633    意味着您希望在对子系统进行更    
634    代码做出更多承诺。                    
635                                                   
636 -  最后,别忘记去阅读 Documentation/p    
637                                                   
638 Kernel 仙女棒                                  
639 ===============                                   
640                                                   
641 浏览源代码时的一些收藏。请随意    
642                                                   
643 ``arch/x86/include/asm/delay.h``::                
644                                                   
645     #define ndelay(n) (__builtin_constant_p(n)    
646             ((n) > 20000 ? __bad_ndelay() : __    
647             __ndelay(n))                          
648                                                   
649                                                   
650 ``include/linux/fs.h``::                          
651                                                   
652     /*                                            
653      * Kernel pointers have redundant informat    
654      * scheme where we can return either an er    
655      * pointer with the same return value.        
656      *                                            
657      * This should be a per-architecture thing    
658      * error and pointer decisions.               
659      */                                           
660      #define ERR_PTR(err)    ((void *)((long)(    
661      #define PTR_ERR(ptr)    ((long)(ptr))        
662      #define IS_ERR(ptr)     ((unsigned long)(    
663                                                   
664 ``arch/x86/include/asm/uaccess_32.h:``::          
665                                                   
666     #define copy_to_user(to,from,n)               
667             (__builtin_constant_p(n) ?            
668              __constant_copy_to_user((to),(fro    
669              __generic_copy_to_user((to),(from    
670                                                   
671                                                   
672 ``arch/sparc/kernel/head.S:``::                   
673                                                   
674     /*                                            
675      * Sun people can't spell worth damn. "com    
676      * At least we *know* we can't spell, and     
677      */                                           
678                                                   
679     /* Uh, actually Linus it is I who cannot s    
680      * Sparc assembly will do this to ya.         
681      */                                           
682     C_LABEL(cputypvar):                           
683             .asciz "compatibility"                
684                                                   
685     /* Tested on SS-5, SS-10. Probably someone    
686             .align 4                              
687     C_LABEL(cputypvar_sun4m):                     
688             .asciz "compatible"                   
689                                                   
690                                                   
691 ``arch/sparc/lib/checksum.S:``::                  
692                                                   
693             /* Sun, you just can't beat me, yo    
694              * give up.  I'm serious, I am goi    
695              * out of you, game over, lights o    
696              */                                   
697                                                   
698                                                   
699 致谢                                            
700 =====                                             
701                                                   
702 感谢Andi Kleen提出点子,回答我的问    
703 感谢Philipp Rumpf做了许多拼写和清晰    
704 感谢Werner Almesberger对 :c:func:`disable_i    
705 Jes Sorensen和Andrea Arcangeli补充了一些    
706 感谢Michael Elizabeth Chastain检查并补    
707 感谢Telsa Gwynne教我DocBook。                
                                                      

~ [ 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