Chinese translated version of Documentation/CodingStyle If you have any comment or update to the content, please post to LKML directly. However, if you have problem communicating in English you can also ask the Chinese maintainer for help. Contact the Chinese maintainer, if this translation is outdated or there is problem with translation. Chinese maintainer: Zhang Le <r0bertz@gentoo.org> --------------------------------------------------------------------- Documentation/CodingStyleçä¸æç¿»è¯ å¦ææ³è¯è®ºææ´æ°æ¬æçå 容ï¼è¯·ç´æ¥åä¿¡å°LKMLãå¦æä½ ä½¿ç¨è±æ交æµæå°é¾çè¯ï¼ä¹å¯ 以åä¸æçç»´æ¤è æ±å©ãå¦ææ¬ç¿»è¯æ´æ°ä¸åæ¶æè ç¿»è¯åå¨é®é¢ï¼è¯·èç³»ä¸æçç»´æ¤è ã ä¸æçç»´æ¤è ï¼ å¼ ä¹ Zhang Le <r0bertz@gentoo.org> ä¸æçç¿»è¯è ï¼ å¼ ä¹ Zhang Le <r0bertz@gentoo.org> ä¸æçæ ¡è¯è ï¼ çèª Wang Cong <xiyou.wangcong@gmail.com> wheelz <kernel.zeng@gmail.com> 管æä¸ Xudong Guan <xudong.guan@gmail.com> Li Zefan <lizf@cn.fujitsu.com> Wang Chen <wangchen@cn.fujitsu.com> 以ä¸ä¸ºæ£æ --------------------------------------------------------------------- Linuxå æ ¸ä»£ç é£æ ¼ è¿æ¯ä¸ä¸ªç®ççææ¡£ï¼æè¿°äº linux å æ ¸çé¦é代ç é£æ ¼ã代ç é£æ ¼æ¯å 人èå¼çï¼èä¸æ ä¸æ¿ææèªå·±çè§ç¹å¼ºå ç»ä»»ä½äººï¼ä½è¿å°±åæå»åä»»ä½äºæ é½å¿ é¡»éµå¾ªçååé£æ ·ï¼æä¹ å¸æå¨ç»å¤§å¤æ°äºä¸ä¿æè¿ç§çæ度ã请ï¼å¨å代ç æ¶ï¼è³å°èèä¸ä¸è¿éç代ç é£æ ¼ã é¦å ï¼æå»ºè®®ä½ æå°ä¸ä»½ GNU 代ç è§èï¼ç¶åä¸è¦è¯»ãç§äºå®ï¼è¿æ¯ä¸ä¸ªå ·æé大象å¾æ§æä¹ çå¨ä½ã ä¸ç®¡ææ ·ï¼ç°å¨æ们å¼å§ï¼ 第ä¸ç« ï¼ç¼©è¿ å¶è¡¨ç¬¦æ¯ 8 个å符ï¼æ以缩è¿ä¹æ¯ 8 个å符ãæäºå¼ç«¯è¿å¨è¯å¾å°ç¼©è¿å为 4ï¼çè³ 2ï¼ï¼ 个å符深ï¼è¿å ä¹ç¸å½äºå°è¯å°åå¨ççå¼å®ä¹ä¸º 3ã çç±ï¼ç¼©è¿çå ¨é¨æä¹å°±å¨äºæ¸ æ¥çå®ä¹ä¸ä¸ªæ§å¶åèµ·æ¢äºä½å¤ãå°¤å ¶æ¯å½ä½ ç¯çä½ çå±å¹ è¿ç»çäº 20 å°æ¶ä¹åï¼ä½ å°ä¼åç°å¤§ä¸ç¹ç缩è¿ä¼ä½¿ä½ æ´å®¹æå辨缩è¿ã ç°å¨ï¼æäºäººä¼æ±æ¨ 8 个å符ç缩è¿ä¼ä½¿ä»£ç åå³è¾¹ç§»å¨ç太è¿ï¼å¨ 80 个å符çç»ç«¯å±å¹ä¸ å°±å¾é¾è¯»è¿æ ·ç代ç ãè¿ä¸ªé®é¢ççæ¡æ¯ï¼å¦æä½ éè¦ 3 级以ä¸ç缩è¿ï¼ä¸ç®¡ç¨ä½ç§æ¹å¼ä½ ç代ç å·²ç»æé®é¢äºï¼åºè¯¥ä¿®æ£ä½ çç¨åºã ç®èè¨ä¹ï¼8 个å符ç缩è¿å¯ä»¥è®©ä»£ç æ´å®¹æé 读ï¼è¿æä¸ä¸ªå¥½å¤æ¯å½ä½ çå½æ°åµå¥å¤ªæ·±ç æ¶åå¯ä»¥ç»ä½ è¦åãçå¿è¿ä¸ªè¦åã å¨ switch è¯å¥ä¸æ¶é¤å¤çº§ç¼©è¿çé¦éçæ¹å¼æ¯è®© âswitchâ åä»å±äºå®ç âcaseâ æ ç¾ å¯¹é½äºåä¸åï¼èä¸è¦ â两次缩è¿â âcaseâ æ ç¾ãæ¯å¦ï¼ switch (suffix) { case 'G': case 'g': mem <<= 30; break; case 'M': case 'm': mem <<= 20; break; case 'K': case 'k': mem <<= 10; /* fall through */ default: break; } ä¸è¦æå¤ä¸ªè¯å¥æ¾å¨ä¸è¡éï¼é¤éä½ æä»ä¹ä¸è¥¿è¦éèï¼ if (condition) do_this; do_something_everytime; ä¹ä¸è¦å¨ä¸è¡éæ¾å¤ä¸ªèµå¼è¯å¥ãå æ ¸ä»£ç é£æ ¼è¶ 级ç®åãå°±æ¯é¿å å¯è½å¯¼è´å«äººè¯¯è¯»ç表 è¾¾å¼ã é¤äºæ³¨éãææ¡£å Kconfig ä¹å¤ï¼ä¸è¦ä½¿ç¨ç©ºæ ¼æ¥ç¼©è¿ï¼åé¢çä¾åæ¯ä¾å¤ï¼æ¯ææ为ä¹ã éç¨ä¸ä¸ªå¥½çç¼è¾å¨ï¼ä¸è¦å¨è¡å°¾çç©ºæ ¼ã 第äºç« ï¼æé¿çè¡åå符串ææ£ ä»£ç é£æ ¼çæä¹å°±å¨äºä½¿ç¨å¹³å¸¸ä½¿ç¨çå·¥å ·æ¥ç»´æ代ç çå¯è¯»æ§åå¯ç»´æ¤æ§ã æ¯ä¸è¡çé¿åº¦çéå¶æ¯ 80 åï¼æ们强ç建议æ¨éµå®è¿ä¸ªæ¯ä¾ã é¿äº 80 åçè¯å¥è¦ææ£æææä¹çç段ãé¤éè¶ è¿ 80 åè½æ¾èå¢å å¯è¯»æ§ï¼å¹¶ä¸ä¸ä¼éè ä¿¡æ¯ãåç段è¦ææ¾çäºæ¯ç段ï¼å¹¶ææ¾é å³ãè¿åæ ·éç¨äºæçå¾é¿åæ°å表çå½æ°å¤´ã ç¶èï¼ç»å¯¹ä¸è¦ææ£å¯¹ç¨æ·å¯è§çå符串ï¼ä¾å¦ printk ä¿¡æ¯ï¼å 为è¿å°å¯¼è´æ æ³ grep è¿äº ä¿¡æ¯ã 第ä¸ç« ï¼å¤§æ¬å·åç©ºæ ¼çæ¾ç½® Cè¯è¨é£æ ¼ä¸å¦å¤ä¸ä¸ªå¸¸è§é®é¢æ¯å¤§æ¬å·çæ¾ç½®ãå缩è¿å¤§å°ä¸åï¼éæ©æå¼ç¨æç§æ¾ç½®ç ç¥å¹¶æ²¡æå¤å°ææ¯ä¸çåå ï¼ä¸è¿é¦éçæ¹å¼ï¼å°±å Kernighan å Ritchie å±ç¤ºç»æ们çï¼ æ¯æèµ·å§å¤§æ¬å·æ¾å¨è¡å°¾ï¼èæç»æ大æ¬å·æ¾å¨è¡é¦ï¼æä»¥ï¼ if (x is true) { we do y } è¿éç¨äºææçéå½æ°è¯å¥åï¼ifãswitchãforãwhileãdoï¼ãæ¯å¦ï¼ switch (action) { case KOBJ_ADD: return "add"; case KOBJ_REMOVE: return "remove"; case KOBJ_CHANGE: return "change"; default: return NULL; } ä¸è¿ï¼æä¸ä¸ªä¾å¤ï¼é£å°±æ¯å½æ°ï¼å½æ°çèµ·å§å¤§æ¬å·æ¾ç½®äºä¸ä¸è¡çå¼å¤´ï¼æä»¥ï¼ int function(int x) { body of function } å ¨ä¸ççå¼ç«¯å¯è½ä¼æ±æ¨è¿ä¸ªä¸ä¸è´æ§æ¯â¦â¦åâ¦â¦ä¸ä¸è´çï¼ä¸è¿æææç»´å¥å ¨ç人é½ç¥é (a) K&R æ¯ _æ£ç¡®ç_ï¼å¹¶ä¸ (b) K&R æ¯æ£ç¡®çãæ¤å¤ï¼ä¸ç®¡ææ ·å½æ°é½æ¯ç¹æ®çï¼C å½æ°æ¯ä¸è½åµå¥çï¼ã 注æç»æ大æ¬å·ç¬èªå æ®ä¸è¡ï¼é¤éå®åé¢è·çåä¸ä¸ªè¯å¥çå©ä½é¨åï¼ä¹å°±æ¯ do è¯å¥ä¸ç âwhileâ æè if è¯å¥ä¸ç âelseâï¼åè¿æ ·ï¼ do { body of do-loop } while (condition); å if (x == y) { .. } else if (x > y) { ... } else { .... } çç±ï¼K&Rã ä¹è¯·æ³¨æè¿ç§å¤§æ¬å·çæ¾ç½®æ¹å¼ä¹è½ä½¿ç©ºï¼æè å·®ä¸å¤ç©ºçï¼è¡çæ°éæå°åï¼åæ¶ä¸å¤±å¯ 读æ§ãå æ¤ï¼ç±äºä½ çå±å¹ä¸çæ°è¡æ¯ä¸å¯åçèµæºï¼æ³æ³ 25 è¡çç»ç«¯å±å¹ï¼ï¼ä½ å°ä¼ææ´ å¤ç空è¡æ¥æ¾ç½®æ³¨éã å½åªæä¸ä¸ªåç¬çè¯å¥çæ¶åï¼ä¸ç¨å ä¸å¿ è¦ç大æ¬å·ã if (condition) action(); å if (condition) do_this(); else do_that(); è¿å¹¶ä¸éç¨äºåªæä¸ä¸ªæ¡ä»¶åæ¯æ¯åè¯å¥çæ åµï¼è¿æ¶ææåæ¯é½è¦ä½¿ç¨å¤§æ¬å·ï¼ if (condition) { do_this(); do_that(); } else { otherwise(); } 3.1ï¼ç©ºæ ¼ Linux å æ ¸çç©ºæ ¼ä½¿ç¨æ¹å¼ï¼ä¸»è¦ï¼åå³äºå®æ¯ç¨äºå½æ°è¿æ¯å ³é®åãï¼å¤§å¤æ°ï¼å ³é®åå è¦å ä¸ä¸ªç©ºæ ¼ãå¼å¾æ³¨æçä¾å¤æ¯ sizeofãtypeofãalignof å __attribute__ï¼è¿äº å ³é®åæäºç¨åº¦ä¸çèµ·æ¥æ´åå½æ°ï¼å®ä»¬å¨ Linux éä¹å¸¸å¸¸ä¼´éå°æ¬å·è使ç¨ï¼å°½ç®¡å¨ C é è¿æ ·çå°æ¬å·ä¸æ¯å¿ éçï¼å°±å âstruct fileinfo infoâ 声æè¿åç âsizeof infoâï¼ã æ以å¨è¿äºå ³é®åä¹åæ¾ä¸ä¸ªç©ºæ ¼ï¼ if, switch, case, for, do, while ä½æ¯ä¸è¦å¨ sizeofãtypeofãalignof æè __attribute__ è¿äºå ³é®åä¹åæ¾ç©ºæ ¼ãä¾å¦ï¼ s = sizeof(struct file); ä¸è¦å¨å°æ¬å·éç表达å¼ä¸¤ä¾§å ç©ºæ ¼ãè¿æ¯ä¸ä¸ªåä¾ï¼ s = sizeof( struct file ); å½å£°ææéç±»åæè è¿åæéç±»åçå½æ°æ¶ï¼â*â çé¦é使ç¨æ¹å¼æ¯ä½¿ä¹é è¿åéåæè å½ æ°åï¼èä¸æ¯é è¿ç±»ååãä¾åï¼ char *linux_banner; unsigned long long memparse(char *ptr, char **retptr); char *match_strdup(substring_t *s); å¨å¤§å¤æ°äºå åä¸å æä½ç¬¦ä¸¤ä¾§ä½¿ç¨ä¸ä¸ªç©ºæ ¼ï¼ä¾å¦ä¸é¢ææè¿äºæä½ç¬¦ï¼ = + - < > * / % | & ^ <= >= == != ? : ä½æ¯ä¸å æä½ç¬¦åä¸è¦å ç©ºæ ¼ï¼ & * + - ~ ! sizeof typeof alignof __attribute__ defined åç¼èªå åèªåä¸å æä½ç¬¦åä¸å ç©ºæ ¼ï¼ ++ -- åç¼èªå åèªåä¸å æä½ç¬¦åä¸å ç©ºæ ¼ï¼ ++ -- â.â å â->â ç»æä½æåæä½ç¬¦ååä¸å ç©ºæ ¼ã ä¸è¦å¨è¡å°¾ç空ç½ãæäºå¯ä»¥èªå¨ç¼©è¿çç¼è¾å¨ä¼å¨æ°è¡çè¡é¦å å ¥ééç空ç½ï¼ç¶åä½ å°±å¯ä»¥ç´æ¥å¨é£ä¸è¡è¾å ¥ä»£ç ãä¸è¿åå¦ä½ æå没æå¨é£ä¸è¡è¾å ¥ä»£ç ï¼æäºç¼è¾å¨å°±ä¸ ä¼ç§»é¤å·²ç»å å ¥ç空ç½ï¼å°±åä½ æ æçä¸ä¸ä¸ªåªæ空ç½çè¡ãå å«è¡å°¾ç©ºç½çè¡å°±è¿æ ·äº§ çäºã å½gitåç°è¡¥ä¸å å«äºè¡å°¾ç©ºç½çæ¶åä¼è¦åä½ ï¼å¹¶ä¸å¯ä»¥åºä½ çè¦æ±å»æè¡å°¾ç©ºç½ï¼ä¸è¿ å¦æä½ æ¯æ£å¨æä¸ç³»åè¡¥ä¸ï¼è¿æ ·åä¼å¯¼è´åé¢çè¡¥ä¸å¤±è´¥ï¼å ä¸ºä½ æ¹åäºè¡¥ä¸çä¸ä¸æã 第åç« ï¼å½å Cæ¯ä¸ä¸ªç®æ´çè¯è¨ï¼ä½ çå½åä¹åºè¯¥è¿æ ·ãå Modula-2 å Pascal ç¨åºåä¸åï¼C ç¨åºå ä¸ä½¿ç¨ç±»ä¼¼ ThisVariableIsATemporaryCounter è¿æ ·å丽çååãC ç¨åºåä¼ç§°é£ä¸ªåé 为 âtmpâï¼è¿æ ·åèµ·æ¥ä¼æ´å®¹æï¼èä¸è³å°ä¸ä¼ä»¤å ¶é¾äºç解ã ä¸è¿ï¼è½ç¶æ··ç¨å¤§å°åçååæ¯ä¸æå¡ä½¿ç¨çï¼ä½æ¯å ¨å±åéè¿æ¯éè¦ä¸ä¸ªå ·æè¿°æ§çåå ã称ä¸ä¸ªå ¨å±å½æ°ä¸º âfooâ æ¯ä¸ä¸ªé¾ä»¥é¥¶æçé误ã å ¨å±åéï¼åªæå½ä½ çæ£éè¦å®ä»¬çæ¶ååç¨å®ï¼éè¦æä¸ä¸ªå ·æè¿°æ§çååï¼å°±åå ¨å±å½ æ°ãå¦æä½ æä¸ä¸ªå¯ä»¥è®¡ç®æ´»å¨ç¨æ·æ°éçå½æ°ï¼ä½ åºè¯¥å«å® âcount_active_users()â æè 类似çååï¼ä½ ä¸åºè¯¥å«å® âcntuser()âã å¨å½æ°åä¸å å«å½æ°ç±»åï¼æè°çåçå©å½åæ³ï¼æ¯èååºäºé®é¢ââç¼è¯å¨ç¥éé£äºç±»åè ä¸è½å¤æ£æ¥é£äºç±»åï¼è¿æ ·ååªè½æç¨åºåå¼ç³æ¶äºãé¾æªå¾®è½¯æ»æ¯å¶é åºæé®é¢çç¨åºã æ¬å°åéååºè¯¥ç®çï¼èä¸è½å¤è¡¨è¾¾ç¸å ³çå«ä¹ãå¦æä½ æä¸äºéæºçæ´æ°åç循ç¯è®¡æ°å¨ ï¼å®åºè¯¥è¢«ç§°ä¸º âiâãå«å® âloop_counterâ 并æ çå¤ï¼å¦æå®æ²¡æ被误解çå¯è½çè¯ã 类似çï¼âtmpâ å¯ä»¥ç¨æ¥ç§°å¼ä»»æç±»åç临æ¶åéã å¦æä½ ææ··æ·äºä½ çæ¬å°åéåï¼ä½ å°±éå°å¦ä¸ä¸ªé®é¢äºï¼å«åå½æ°å¢é¿è·å°è失衡综åç ã请ç第å ç« ï¼å½æ°ï¼ã 第äºç« ï¼Typedef ä¸è¦ä½¿ç¨ç±»ä¼¼ âvps_tâ ä¹ç±»çä¸è¥¿ã 对ç»æä½åæéä½¿ç¨ typedef æ¯ä¸ä¸ªé误ãå½ä½ å¨ä»£ç éçå°ï¼ vps_t a; è¿ä»£è¡¨ä»ä¹ææå¢ï¼ ç¸åï¼å¦ææ¯è¿æ · struct virtual_container *a; ä½ å°±ç¥é âaâ æ¯ä»ä¹äºã å¾å¤äººè®¤ä¸º typedef âè½æé«å¯è¯»æ§âãå®é ä¸æ¯è¿æ ·çãå®ä»¬åªå¨ä¸åæ åµä¸æç¨ï¼ (a) å®å ¨ä¸éæç对象ï¼è¿ç§æ åµä¸è¦ä¸»å¨ä½¿ç¨ typedef æ¥éèè¿ä¸ªå¯¹è±¡å®é ä¸æ¯ä»ä¹ï¼ã ä¾å¦ï¼âpte_tâ çä¸éæ对象ï¼ä½ åªè½ç¨åéç访é®å½æ°æ¥è®¿é®å®ä»¬ã 注æï¼ä¸éææ§åâ访é®å½æ°âæ¬èº«æ¯ä¸å¥½çãæä»¬ä½¿ç¨ pte_t çç±»åçåå å¨äºççæ¯ å®å ¨æ²¡æä»»ä½å ±ç¨çå¯è®¿é®ä¿¡æ¯ã (b) æ¸ æ¥çæ´æ°ç±»åï¼å¦æ¤ï¼è¿å±æ½è±¡å°±å¯ä»¥å¸®å©æ¶é¤å°åºæ¯ âintâ è¿æ¯ âlongâ çæ··æ·ã u8/u16/u32 æ¯å®å ¨æ²¡æé®é¢ç typedefï¼ä¸è¿å®ä»¬æ´ç¬¦åç±»å« (d) èä¸æ¯è¿éã å次注æï¼è¦è¿æ ·åï¼å¿ é¡»äºåºæå ãå¦ææ个åéæ¯ âunsigned longâï¼é£ä¹æ²¡æå¿ è¦ typedef unsigned long myflags_t; ä¸è¿å¦ææä¸ä¸ªæç¡®çåå ï¼æ¯å¦å®å¨æç§æ åµä¸å¯è½ä¼æ¯ä¸ä¸ª âunsigned intâ èå¨ å ¶ä»æ åµä¸å¯è½ä¸º âunsigned longâï¼é£ä¹å°±ä¸è¦ç¹è±«ï¼è¯·å¡å¿ ä½¿ç¨ typedefã (c) å½ä½ 使ç¨sparseæåé¢çå建ä¸ä¸ªæ°ç±»åæ¥åç±»åæ£æ¥çæ¶åã (d) åæ åC99ç±»åç¸åçç±»åï¼å¨æäºä¾å¤çæ åµä¸ã è½ç¶è®©ç¼çåèçæ¥éåºæ°çæ åç±»åæ¯å¦ âuint32_tâ ä¸éè¦è±å¾å¤æ¶é´ï¼å¯æ¯æäº äººä»ç¶æç»ä½¿ç¨å®ä»¬ã å æ¤ï¼Linux ç¹æççåäºæ åç±»åç âu8/u16/u32/u64â ç±»ååå®ä»¬çæ符å·ç±»åæ¯è¢« å 许çââ尽管å¨ä½ èªå·±çæ°ä»£ç ä¸ï¼å®ä»¬ä¸æ¯å¼ºå¶è¦æ±è¦ä½¿ç¨çã å½ç¼è¾å·²ç»ä½¿ç¨äºæ个类åéçå·²æ代ç æ¶ï¼ä½ åºè¯¥éµå¾ªé£äºä»£ç ä¸å·²ç»ååºçéæ©ã (e) å¯ä»¥å¨ç¨æ·ç©ºé´å®å ¨ä½¿ç¨çç±»åã å¨æäºç¨æ·ç©ºé´å¯è§çç»æä½éï¼æ们ä¸è½è¦æ±C99ç±»åèä¸ä¸è½ç¨ä¸é¢æå°ç âu32â ç±»åãå æ¤ï¼æ们å¨ä¸ç¨æ·ç©ºé´å ±äº«çææç»æä½ä¸ä½¿ç¨ __u32 å类似çç±»åã å¯è½è¿æå ¶ä»çæ åµï¼ä¸è¿åºæ¬çè§åæ¯æ°¸è¿ä¸è¦ä½¿ç¨ typedefï¼é¤éä½ å¯ä»¥æç¡®çåºç¨ä¸ è¿°æ个è§åä¸çä¸ä¸ªã æ»çæ¥è¯´ï¼å¦æä¸ä¸ªæéæè ä¸ä¸ªç»æä½éçå ç´ å¯ä»¥åçç被ç´æ¥è®¿é®å°ï¼é£ä¹å®ä»¬å°±ä¸ åºè¯¥æ¯ä¸ä¸ª typedefã 第å ç« ï¼å½æ° å½æ°åºè¯¥ç®çèæ¼äº®ï¼å¹¶ä¸åªå®æä¸ä»¶äºæ ãå½æ°åºè¯¥å¯ä»¥ä¸å±æè 两å±æ¾ç¤ºå®ï¼æ们é½ç¥ é ISO/ANSI å±å¹å¤§å°æ¯ 80x24ï¼ï¼åªåä¸ä»¶äºæ ï¼èä¸æå®å好ã ä¸ä¸ªå½æ°çæ大é¿åº¦æ¯å该å½æ°çå¤æ度å缩è¿çº§æ°æåæ¯çãæ以ï¼å¦æä½ æä¸ä¸ªçè®ºä¸ å¾ç®åçåªæä¸ä¸ªå¾é¿ï¼ä½æ¯ç®åï¼ç case è¯å¥çå½æ°ï¼èä¸ä½ éè¦å¨æ¯ä¸ª case éå å¾å¤å¾å°çäºæ ï¼è¿æ ·çå½æ°å°½ç®¡å¾é¿ï¼ä½ä¹æ¯å¯ä»¥çã ä¸è¿ï¼å¦æä½ æä¸ä¸ªå¤æçå½æ°ï¼èä¸ä½ æçä¸ä¸ªå¤©åä¸æ¯å¾é«çé«ä¸ä¸å¹´çº§å¦çå¯è½çè³ æä¸æ¸ æ¥è¿ä¸ªå½æ°çç®çï¼ä½ åºè¯¥ä¸¥æ ¼çéµå®åé¢æå°çé¿åº¦éå¶ã使ç¨è¾ å©å½æ°ï¼å¹¶ä¸ºä¹ åä¸ªå ·æè¿°æ§çååï¼å¦æä½ è§å¾å®ä»¬çæ§è½å¾éè¦çè¯ï¼å¯ä»¥è®©ç¼è¯å¨å èå®ä»¬ï¼è¿æ ·ç ææå¾å¾ä¼æ¯ä½ åä¸ä¸ªå¤æå½æ°çææè¦å¥½ãï¼ å½æ°çå¦å¤ä¸ä¸ªè¡¡éæ åæ¯æ¬å°åéçæ°éãæ¤æ°éä¸åºè¶ è¿ 5ï¼10 个ï¼å¦åä½ çå½æ°å°±æ é®é¢äºãéæ°èèä¸ä¸ä½ çå½æ°ï¼æå®åæææ´å°çå½æ°ã人ç大èä¸è¬å¯ä»¥è½»æ¾çåæ¶è· 踪 7 个ä¸åçäºç©ï¼å¦æåå¢å¤çè¯ï¼å°±ä¼ç³æ¶äºãå³ä¾¿ä½ èªé¢è¿äººï¼ä½ ä¹å¯è½ä¼è®°ä¸æ¸ ä½ 2 个ææååè¿çäºæ ã å¨æºæ件éï¼ä½¿ç¨ç©ºè¡éå¼ä¸åçå½æ°ãå¦æ该å½æ°éè¦è¢«å¯¼åºï¼å®ç EXPORT* å®åºè¯¥ç´§è´´ å¨å®çç»æ大æ¬å·ä¹ä¸ãæ¯å¦ï¼ int system_is_up(void) { return system_state == SYSTEM_RUNNING; } EXPORT_SYMBOL(system_is_up); å¨å½æ°ååä¸ï¼å å«å½æ°ååå®ä»¬çæ°æ®ç±»åãè½ç¶Cè¯è¨é没æè¿æ ·çè¦æ±ï¼å¨ Linux éè¿ æ¯æå¡çåæ³ï¼å 为è¿æ ·å¯ä»¥å¾ç®åçç»è¯»è æä¾æ´å¤çæä»·å¼çä¿¡æ¯ã 第ä¸ç« ï¼éä¸çå½æ°éåºéå¾ è½ç¶è¢«æäºäººå£°ç§°å·²ç»è¿æ¶ï¼ä½æ¯ goto è¯å¥ççä»·ç©è¿æ¯ç»å¸¸è¢«ç¼è¯å¨æ使ç¨ï¼å ·ä½å½¢å¼æ¯ æ æ¡ä»¶è·³è½¬æ令ã å½ä¸ä¸ªå½æ°ä»å¤ä¸ªä½ç½®éåºï¼å¹¶ä¸éè¦åä¸äºç±»ä¼¼æ¸ çç常è§æä½æ¶ï¼goto è¯å¥å°±å¾æ¹ä¾¿äºã å¦æ并ä¸éè¦æ¸ çæä½ï¼é£ä¹ç´æ¥ return å³å¯ã çç±æ¯ï¼ - æ æ¡ä»¶è¯å¥å®¹æç解åè·è¸ª - åµå¥ç¨åº¦åå° - å¯ä»¥é¿å ç±äºä¿®æ¹æ¶å¿è®°æ´æ°æ个åç¬çéåºç¹è导è´çé误 - åè½»äºç¼è¯å¨çå·¥ä½ï¼æ éå é¤åä½ä»£ç ;) int fun(int a) { int result = 0; char *buffer; buffer = kmalloc(SIZE, GFP_KERNEL); if (!buffer) return -ENOMEM; if (condition1) { while (loop1) { ... } result = 1; goto out_buffer; } ... out_buffer: kfree(buffer); return result; } ä¸ä¸ªéè¦æ³¨æç常è§é误æ¯âä¸ä¸ª err é误âï¼å°±åè¿æ ·ï¼ err: kfree(foo->bar); kfree(foo); return ret; è¿æ®µä»£ç çé误æ¯ï¼å¨æäºéåºè·¯å¾ä¸ âfooâ æ¯ NULLãé常æ åµä¸ï¼éè¿æå®å离æ两个 é误æ ç¾ âerr_bar:â å âerr_foo:â æ¥ä¿®å¤è¿ä¸ªé误ã ç¬¬å «ç« ï¼æ³¨é 注éæ¯å¥½çï¼ä¸è¿æè¿åº¦æ³¨éçå±é©ãæ°¸è¿ä¸è¦å¨æ³¨éé解éä½ ç代ç æ¯å¦ä½è¿ä½çï¼æ´å¥½ çåæ³æ¯è®©å«äººä¸çä½ ç代ç å°±å¯ä»¥æç½ï¼è§£éåçå¾å·®ç代ç æ¯æµªè´¹æ¶é´ã ä¸è¬çï¼ä½ æ³è¦ä½ ç注éåè¯å«äººä½ ç代ç åäºä»ä¹ï¼èä¸æ¯æä¹åçãä¹è¯·ä½ ä¸è¦æ注é æ¾å¨ä¸ä¸ªå½æ°ä½å é¨ï¼å¦æå½æ°å¤æå°ä½ éè¦ç¬ç«ç注éå ¶ä¸çä¸é¨åï¼ä½ å¾å¯è½éè¦åå° ç¬¬å ç« çä¸çãä½ å¯ä»¥åä¸äºå°æ³¨éæ¥æ³¨ææè¦åæäºå¾èªæï¼æè 槽ç³ï¼çåæ³ï¼ä½ä¸è¦ å 太å¤ãä½ åºè¯¥åçï¼æ¯æ注éæ¾å¨å½æ°ç头é¨ï¼åè¯äººä»¬å®åäºä»ä¹ï¼ä¹å¯ä»¥å ä¸å®åè¿ äºäºæ çåå ã å½æ³¨éå æ ¸APIå½æ°æ¶ï¼è¯·ä½¿ç¨ kernel-doc æ ¼å¼ã请ç Documentation/kernel-documentation.rståscripts/kernel-doc 以è·å¾è¯¦ç»ä¿¡æ¯ã Linuxç注éé£æ ¼æ¯ C89 â/* ... */â é£æ ¼ãä¸è¦ä½¿ç¨ C99 é£æ ¼ â// ...â 注éã é¿ï¼å¤è¡ï¼çé¦é注éé£æ ¼æ¯ï¼ /* * This is the preferred style for multi-line * comments in the Linux kernel source code. * Please use it consistently. * * Description: A column of asterisks on the left side, * with beginning and ending almost-blank lines. */ 对äºå¨ net/ å drivers/net/ çæ件ï¼é¦éçé¿ï¼å¤è¡ï¼æ³¨éé£æ ¼æäºä¸åã /* The preferred comment style for files in net/ and drivers/net * looks like this. * * It is nearly the same as the generally preferred comment style, * but there is no initial almost-blank line. */ 注éæ°æ®ä¹æ¯å¾éè¦çï¼ä¸ç®¡æ¯åºæ¬ç±»åè¿æ¯è¡çç±»åã为äºæ¹ä¾¿å®ç°è¿ä¸ç¹ï¼æ¯ä¸è¡åºåª 声æä¸ä¸ªæ°æ®ï¼ä¸è¦ä½¿ç¨éå·æ¥ä¸æ¬¡å£°æå¤ä¸ªæ°æ®ï¼ãè¿æ ·ä½ å°±æ空é´æ¥ä¸ºæ¯ä¸ªæ°æ®åä¸æ®µ å°æ³¨éæ¥è§£éå®ä»¬çç¨éäºã 第ä¹ç« ï¼ä½ å·²ç»æäºæ å¼ç³äº è¿æ²¡ä»ä¹ï¼æ们é½æ¯è¿æ ·ãå¯è½ä½ ç使ç¨äºå¾é¿æ¶é´ Unix çæåå·²ç»åè¯ä½ âGNU emacsâ è½ èªå¨å¸®ä½ æ ¼å¼å C æºä»£ç ï¼èä¸ä½ ä¹æ³¨æå°äºï¼ç¡®å®æ¯è¿æ ·ï¼ä¸è¿å®æ使ç¨çé»è®¤å¼åæ们 æ³è¦çç¸å»çè¿ï¼å®é ä¸ï¼çè³æ¯éæºæçè¿è¦å·®ââæ æ°ä¸ªç´åå¨ GNU emacs éæåæ°¸è¿ä¸ ä¼åé åºä¸ä¸ªå¥½ç¨åºï¼ï¼è¯æ³¨ï¼è¯·åè Infinite Monkey Theoremï¼ æä»¥ä½ è¦ä¹æ¾å¼ GNU emacsï¼è¦ä¹æ¹åå®è®©å®ä½¿ç¨æ´åçç设å®ãè¦éç¨åä¸ä¸ªæ¹æ¡ï¼ä½ å¯ ä»¥æä¸é¢è¿æ®µç²è´´å°ä½ ç .emacs æ件éã (defun c-lineup-arglist-tabs-only (ignored) "Line up argument lists by tabs, not spaces" (let* ((anchor (c-langelem-pos c-syntactic-element)) (column (c-langelem-2nd-pos c-syntactic-element)) (offset (- (1+ column) anchor)) (steps (floor offset c-basic-offset))) (* (max steps 1) c-basic-offset))) (add-hook 'c-mode-common-hook (lambda () ;; Add kernel style (c-add-style "linux-tabs-only" '("linux" (c-offsets-alist (arglist-cont-nonempty c-lineup-gcc-asm-reg c-lineup-arglist-tabs-only)))))) (add-hook 'c-mode-hook (lambda () (let ((filename (buffer-file-name))) ;; Enable kernel mode for the appropriate files (when (and filename (string-match (expand-file-name "~/src/linux-trees") filename)) (setq indent-tabs-mode t) (setq show-trailing-whitespace t) (c-set-style "linux-tabs-only"))))) è¿ä¼è®© emacs å¨ ~/src/linux-trees ç®å½ä¸ç C æºæ件è·å¾æ´å¥½çå æ ¸ä»£ç é£æ ¼ã ä¸è¿å°±ç®ä½ å°è¯è®© emacs æ£ç¡®çæ ¼å¼å代ç 失败äºï¼ä¹å¹¶ä¸æå³çä½ å¤±å»äºä¸åï¼è¿å¯ä»¥ç¨ âindentâã ä¸è¿ï¼GNU indent ä¹æå GNU emacs ä¸æ ·æé®é¢ç设å®ï¼æä»¥ä½ éè¦ç»å®ä¸äºå½ä»¤é项ãä¸ è¿ï¼è¿è¿ä¸ç®å¤ªç³ç³ï¼å 为就ç®æ¯ GNU indent çä½è ä¹è®¤å K&R çæå¨æ§ï¼GNU ç人并ä¸æ¯ å人ï¼ä»ä»¬åªæ¯å¨è¿ä¸ªé®é¢ä¸è¢«ä¸¥éç误导äºï¼ï¼æä»¥ä½ åªè¦ç» indent æå®é项 â-kr -i8â ï¼ä»£è¡¨ âK&Rï¼8 个å符缩è¿âï¼ï¼æè ä½¿ç¨ âscripts/Lindentâï¼è¿æ ·å°±å¯ä»¥ä»¥ææ¶é«¦çæ¹å¼ 缩è¿æºä»£ç ã âindentâ æå¾å¤é项ï¼ç¹å«æ¯éæ°æ ¼å¼å注éçæ¶åï¼ä½ å¯è½éè¦çä¸ä¸å®çæå页ãä¸è¿ è®°ä½ï¼âindentâ ä¸è½ä¿®æ£åçç¼ç¨ä¹ æ¯ã 第åç« ï¼Kconfig é ç½®æ件 对äºéå¸æºç æ çææ Kconfig* é ç½®æ件æ¥è¯´ï¼å®ä»¬ç¼©è¿æ¹å¼ä¸ C 代ç ç¸æ¯ææä¸åãç´§æ¨ å¨ âconfigâ å®ä¹ä¸é¢çè¡ç¼©è¿ä¸ä¸ªå¶è¡¨ç¬¦ï¼å¸®å©ä¿¡æ¯ååå¤ç¼©è¿ 2 ä¸ªç©ºæ ¼ãæ¯å¦ï¼ config AUDIT bool "Auditing support" depends on NET help Enable auditing infrastructure that can be used with another kernel subsystem, such as SELinux (which requires this for logging of avc messages output). Does not do system-call auditing without CONFIG_AUDITSYSCALL. èé£äºå±é©çåè½ï¼æ¯å¦æäºæ件系ç»çåæ¯æï¼åºè¯¥å¨å®ä»¬çæ示å符串éæ¾èç声æè¿ ä¸ç¹ï¼ config ADFS_FS_RW bool "ADFS write support (DANGEROUS)" depends on ADFS_FS ... è¦æ¥çé ç½®æ件çå®æ´ææ¡£ï¼è¯·ç Documentation/kbuild/kconfig-language.txtã 第åä¸ç« ï¼æ°æ®ç»æ å¦æä¸ä¸ªæ°æ®ç»æï¼å¨å建åéæ¯å®çå线æ§è¡ç¯å¢ä¹å¤å¯è§ï¼é£ä¹å®å¿ é¡»è¦æä¸ä¸ªå¼ç¨è®¡ æ°å¨ãå æ ¸é没æåå¾æ¶éï¼å¹¶ä¸å æ ¸ä¹å¤çåå¾æ¶éæ ¢ä¸æçä½ä¸ï¼ï¼è¿æå³çä½ ç»å¯¹é è¦è®°å½ä½ 对è¿ç§æ°æ®ç»æç使ç¨æ åµã å¼ç¨è®¡æ°æå³çä½ è½å¤é¿å ä¸éï¼å¹¶ä¸å 许å¤ä¸ªç¨æ·å¹¶è¡è®¿é®è¿ä¸ªæ°æ®ç»æââèä¸éè¦æ å¿ è¿ä¸ªæ°æ®ç»æä» ä» å 为ææ¶ä¸è¢«ä½¿ç¨å°±æ¶å¤±äºï¼é£äºç¨æ·å¯è½ä¸è¿æ¯æ²ç¡äºä¸éµæè åäºä¸ äºå ¶ä»äºæ èå·²ã 注æä¸éä¸è½å代å¼ç¨è®¡æ°ãä¸éæ¯ä¸ºäºä¿ææ°æ®ç»æçä¸è´æ§ï¼èå¼ç¨è®¡æ°æ¯ä¸ä¸ªå å管 çæå·§ãé常äºè é½éè¦ï¼ä¸è¦æ两个ææ··äºã å¾å¤æ°æ®ç»æå®é ä¸æ2级å¼ç¨è®¡æ°ï¼å®ä»¬é常æä¸åâç±»âçç¨æ·ãå类计æ°å¨ç»è®¡åç±»ç¨ æ·çæ°éï¼æ¯å½å类计æ°å¨åè³é¶æ¶ï¼å ¨å±è®¡æ°å¨åä¸ã è¿ç§âå¤çº§å¼ç¨è®¡æ°âçä¾åå¯ä»¥å¨å å管çï¼âstruct mm_structâï¼mm_users å mm_countï¼ åæ件系ç»ï¼âstruct super_blockâï¼s_countås_activeï¼ä¸æ¾å°ã è®°ä½ï¼å¦æå¦ä¸ä¸ªæ§è¡çº¿ç´¢å¯ä»¥æ¾å°ä½ çæ°æ®ç»æï¼ä½æ¯è¿ä¸ªæ°æ®ç»æ没æå¼ç¨è®¡æ°å¨ï¼è¿ éå ä¹è¯å®æ¯ä¸ä¸ª bugã 第åäºç« ï¼å®ï¼æ举åRTL ç¨äºå®ä¹å¸¸éçå®çåååæ举éçæ ç¾éè¦å¤§åã #define CONSTANT 0x12345 å¨å®ä¹å 个ç¸å ³ç常éæ¶ï¼æ好ç¨æ举ã å®çåå请ç¨å¤§ååæ¯ï¼ä¸è¿å½¢å¦å½æ°çå®çååå¯ä»¥ç¨å°ååæ¯ã ä¸è¬çï¼å¦æè½åæå èå½æ°å°±ä¸è¦åæåå½æ°çå®ã å«æå¤ä¸ªè¯å¥çå®åºè¯¥è¢«å å«å¨ä¸ä¸ª do-while 代ç åéï¼ #define macrofun(a, b, c) \ do { \ if (a == 5) \ do_this(b, c); \ } while (0) 使ç¨å®çæ¶ååºé¿å çäºæ ï¼ 1) å½±åæ§å¶æµç¨çå®ï¼ #define FOO(x) \ do { \ if (blah(x) < 0) \ return -EBUGGERED; \ } while (0) é常ä¸å¥½ãå®çèµ·æ¥åä¸ä¸ªå½æ°ï¼ä¸è¿å´è½å¯¼è´âè°ç¨âå®çå½æ°éåºï¼ä¸è¦æ乱读è 大èé çè¯æ³åæå¨ã 2) ä¾èµäºä¸ä¸ªåºå®ååçæ¬å°åéçå®ï¼ #define FOO(val) bar(index, val) å¯è½çèµ·æ¥åæ¯ä¸ªä¸éçä¸è¥¿ï¼ä¸è¿å®é常容ææ读代ç ç人æç³æ¶ï¼èä¸å®¹æ导è´çèµ·æ¥ ä¸ç¸å ³çæ¹å¨å¸¦æ¥é误ã 3) ä½ä¸ºå·¦å¼ç带åæ°çå®ï¼ FOO(x) = yï¼å¦ææ人æ FOO åæä¸ä¸ªå èå½æ°çè¯ï¼è¿ç§ç¨ æ³å°±ä¼åºéäºã 4) å¿è®°äºä¼å 级ï¼ä½¿ç¨è¡¨è¾¾å¼å®ä¹å¸¸éçå®å¿ é¡»å°è¡¨è¾¾å¼ç½®äºä¸å¯¹å°æ¬å·ä¹å ã带åæ°ç å®ä¹è¦æ³¨ææ¤ç±»é®é¢ã #define CONSTANT 0x4000 #define CONSTEXP (CONSTANT | 3) 5) å¨å®éå®ä¹ç±»ä¼¼å½æ°çæ¬å°åéæ¶å½åå²çªï¼ #define FOO(x) \ ({ \ typeof(x) ret; \ ret = calc_ret(x); \ (ret); \ }) ret æ¯æ¬å°åéçéç¨åå - __foo_ret æ´ä¸å®¹æä¸ä¸ä¸ªå·²åå¨çåéå²çªã cpp æå对å®ç讲解å¾è¯¦ç»ãgcc internals æåä¹è¯¦ç»è®²è§£äº RTLï¼è¯æ³¨ï¼register transfer languageï¼ï¼å æ ¸éçæ±ç¼è¯è¨ç»å¸¸ç¨å°å®ã 第åä¸ç« ï¼æå°å æ ¸æ¶æ¯ å æ ¸å¼åè åºè¯¥æ¯åè¿è¯å¥½æè²çã请ä¸å®æ³¨æå æ ¸ä¿¡æ¯çæ¼åï¼ä»¥ç»äººä»¥å¥½çå°è±¡ãä¸è¦ ç¨ä¸è§èçåè¯æ¯å¦ âdontâï¼èè¦ç¨ âdo notâæè âdon'tâãä¿è¯è¿äºä¿¡æ¯ç®åãæäºã æ æ§ä¹ã å æ ¸ä¿¡æ¯ä¸å¿ 以å¥å·ï¼è¯æ³¨ï¼è±æå¥å·ï¼å³ç¹ï¼ç»æã å¨å°æ¬å·éæå°æ°å (%d) 没æä»»ä½ä»·å¼ï¼åºè¯¥é¿å è¿æ ·åã <linux/device.h> éæä¸äºé©±å¨æ¨¡åè¯æå®ï¼ä½ åºè¯¥ä½¿ç¨å®ä»¬ï¼ä»¥ç¡®ä¿ä¿¡æ¯å¯¹åºäºæ£ç¡®ç 设å¤å驱å¨ï¼å¹¶ä¸è¢«æ è®°äºæ£ç¡®çæ¶æ¯çº§å«ãè¿äºå®æï¼dev_err()ï¼dev_warn()ï¼ dev_info() ççã对äºé£äºä¸åæ个ç¹å®è®¾å¤ç¸å ³è¿çä¿¡æ¯ï¼<linux/printk.h> å®ä¹äº pr_notice()ï¼pr_info()ï¼pr_warn()ï¼pr_err() åå ¶ä»ã ååºå¥½çè°è¯ä¿¡æ¯å¯ä»¥æ¯ä¸ä¸ªå¾å¤§çææï¼ä¸æ¦ä½ ååºåï¼è¿äºä¿¡æ¯å¨è¿ç¨é¤éæ¶è½æä¾æ大 ç帮å©ãç¶èæå°è°è¯ä¿¡æ¯çå¤çæ¹å¼åæå°éè°è¯ä¿¡æ¯ä¸åãå ¶ä» pr_XXX() å½æ°è½æ æ¡ä»¶å° æå°ï¼pr_debug() å´ä¸ï¼é»è®¤æ åµä¸å®ä¸ä¼è¢«ç¼è¯ï¼é¤éå®ä¹äº DEBUG æ设å®äº CONFIG_DYNAMIC_DEBUGãå®é è¿åæ ·æ¯ä¸ºäº dev_dbg()ï¼ä¸ä¸ªç¸å ³çº¦å®æ¯å¨ä¸ä¸ªå·²ç»å¼å¯äº DEBUG æ¶ï¼ä½¿ç¨ VERBOSE_DEBUG æ¥æ·»å dev_vdbg()ã 许å¤åç³»ç»æ¥æ Kconfig è°è¯é项æ¥å¼å¯ -DDEBUG å¨å¯¹åºç Makefile éé¢ï¼å¨å ¶ä» æ åµä¸ï¼ç¹æ®æä»¶ä½¿ç¨ #define DEBUGãå½ä¸æ¡è°è¯ä¿¡æ¯éè¦è¢«æ æ¡ä»¶æå°æ¶ï¼ä¾å¦ï¼å¦æ å·²ç»å å«ä¸ä¸ªè°è¯ç¸å ³ç #ifdef æ¡ä»¶ï¼printk(KERN_DEBUG ...) å°±å¯è¢«ä½¿ç¨ã 第ååç« ï¼åé å å å æ ¸æä¾äºä¸é¢çä¸è¬ç¨éçå ååé å½æ°ï¼ kmalloc()ï¼kzalloc()ï¼kmalloc_array()ï¼kcalloc()ï¼vmalloc() å vzalloc()ã 请åè API æ档以è·åæå ³å®ä»¬ç详ç»ä¿¡æ¯ã ä¼ éç»æä½å¤§å°çé¦éå½¢å¼æ¯è¿æ ·çï¼ p = kmalloc(sizeof(*p), ...); å¦å¤ä¸ç§ä¼ éæ¹å¼ä¸ï¼sizeof çæä½æ°æ¯ç»æä½çååï¼è¿æ ·ä¼éä½å¯è¯»æ§ï¼å¹¶ä¸å¯è½ä¼å¼ å ¥ bugãæå¯è½æéåéç±»å被æ¹åæ¶ï¼è对åºçä¼ éç»å ååé å½æ°ç sizeof çç»æä¸åã 强å¶è½¬æ¢ä¸ä¸ª void æéè¿åå¼æ¯å¤ä½çãC è¯è¨æ¬èº«ä¿è¯äºä» void æéå°å ¶ä»ä»»ä½æéç±»å ç转æ¢æ¯æ²¡æé®é¢çã åé ä¸ä¸ªæ°ç»çé¦éå½¢å¼æ¯è¿æ ·çï¼ p = kmalloc_array(n, sizeof(...), ...); åé ä¸ä¸ªé¶é¿æ°ç»çé¦éå½¢å¼æ¯è¿æ ·çï¼ p = kcalloc(n, sizeof(...), ...); 两ç§å½¢å¼æ£æ¥åé å¤§å° n * sizeof(...) ç溢åºï¼å¦æ溢åºè¿å NULLã 第åäºç« ï¼å èå¼ç æä¸ä¸ªå¸¸è§ç误解æ¯å èå½æ°æ¯ gcc æä¾çå¯ä»¥è®©ä»£ç è¿è¡æ´å¿«çä¸ä¸ªé项ãè½ç¶ä½¿ç¨å è å½æ°ææ¶åæ¯æ°å½çï¼æ¯å¦ä½ä¸ºä¸ç§æ¿ä»£å®çæ¹å¼ï¼è¯·ç第åäºç« ï¼ï¼ä¸è¿å¾å¤æ åµä¸ä¸æ¯ è¿æ ·ãinline å ³é®åçè¿åº¦ä½¿ç¨ä¼ä½¿å æ ¸å大ï¼ä»è使æ´ä¸ªç³»ç»è¿è¡é度åæ ¢ãå 为大å æ ¸ ä¼å ç¨æ´å¤çæ令é«éç¼åï¼è¯æ³¨ï¼ä¸çº§ç¼åé常æ¯æ令ç¼ååæ°æ®ç¼ååå¼çï¼èä¸ä¼å¯¼ è´ pagecache çå¯ç¨å ååå°ãæ³è±¡ä¸ä¸ï¼ä¸æ¬¡pagecacheæªå½ä¸å°±ä¼å¯¼è´ä¸æ¬¡ç£ç寻åï¼ å°èæ¶ 5 毫ç§ã5 毫ç§çæ¶é´å CPU è½æ§è¡å¾å¤å¾å¤æ令ã ä¸ä¸ªåºæ¬çååæ¯å¦æä¸ä¸ªå½æ°æ 3 è¡ä»¥ä¸ï¼å°±ä¸è¦æå®åæå èå½æ°ãè¿ä¸ªååçä¸ä¸ªä¾ å¤æ¯ï¼å¦æä½ ç¥éæ个åæ°æ¯ä¸ä¸ªç¼è¯æ¶å¸¸éï¼èä¸å 为è¿ä¸ªå¸¸éä½ ç¡®å®ç¼è¯å¨å¨ç¼è¯æ¶è½ ä¼åæä½ çå½æ°ç大é¨å代ç ï¼é£ä»ç¶å¯ä»¥ç»å®å ä¸ inline å ³é®åãkmalloc() å èå½æ°å°± æ¯ä¸ä¸ªå¾å¥½çä¾åã 人们ç»å¸¸ä¸»å¼ ç» static çèä¸åªç¨äºä¸æ¬¡çå½æ°å ä¸ inlineï¼å¦æ¤ä¸ä¼æä»»ä½æ失ï¼å 为没 æä»ä¹å¥½æè¡¡çãè½ç¶ä»ææ¯ä¸è¯´è¿æ¯æ£ç¡®çï¼ä½æ¯å®é ä¸è¿ç§æ åµä¸å³ä½¿ä¸å inline gcc ä¹å¯ä»¥èªå¨ä½¿å ¶å èãèä¸å ¶ä»ç¨æ·å¯è½ä¼è¦æ±ç§»é¤ inlineï¼ç±æ¤èæ¥çäºè®ºä¼æµæ¶ inline èªèº«çæ½å¨ä»·å¼ï¼å¾ä¸å¿å¤±ã 第åå ç« ï¼å½æ°è¿åå¼åå½å å½æ°å¯ä»¥è¿åå¾å¤ç§ä¸åç±»åçå¼ï¼æ常è§çä¸ç§æ¯è¡¨æå½æ°æ§è¡æåæè 失败çå¼ãè¿æ · çä¸ä¸ªå¼å¯ä»¥è¡¨ç¤ºä¸ºä¸ä¸ªé误代ç æ´æ°ï¼-Exxxï¼å¤±è´¥ï¼0ï¼æåï¼æè ä¸ä¸ªâæåâå¸å°å¼ï¼ 0ï¼å¤±è´¥ï¼é0ï¼æåï¼ã æ··å使ç¨è¿ä¸¤ç§è¡¨è¾¾æ¹å¼æ¯é¾äºåç°ç bug çæ¥æºãå¦æ C è¯è¨æ¬èº«ä¸¥æ ¼åºåæ´å½¢åå¸å°åå éï¼é£ä¹ç¼è¯å¨å°±è½å¤å¸®æ们åç°è¿äºé误â¦â¦ä¸è¿ C è¯è¨ä¸åºåã为äºé¿å 产çè¿ç§ bugï¼è¯· éµå¾ªä¸é¢çæ¯ä¾ï¼ å¦æå½æ°çååæ¯ä¸ä¸ªå¨ä½æè 强å¶æ§çå½ä»¤ï¼é£ä¹è¿ä¸ªå½æ°åºè¯¥è¿åé误代ç æ´ æ°ãå¦ææ¯ä¸ä¸ªå¤æï¼é£ä¹å½æ°åºè¯¥è¿åä¸ä¸ªâæåâå¸å°å¼ã æ¯å¦ï¼âadd workâ æ¯ä¸ä¸ªå½ä»¤ï¼æ以 add_work() å½æ°å¨æåæ¶è¿å 0ï¼å¨å¤±è´¥æ¶è¿å -EBUSYã 类似çï¼å 为 âPCI device presentâ æ¯ä¸ä¸ªå¤æï¼æ以 pci_dev_present() å½æ°å¨æåæ¾å° ä¸ä¸ªå¹é ç设å¤æ¶åºè¯¥è¿å 1ï¼å¦ææ¾ä¸å°æ¶åºè¯¥è¿å 0ã ææ导åºï¼è¯æ³¨ï¼EXPORTï¼çå½æ°é½å¿ é¡»éµå®è¿ä¸ªæ¯ä¾ï¼ææçå ¬å ±å½æ°ä¹é½åºè¯¥å¦æ¤ãç§ æï¼staticï¼å½æ°ä¸éè¦å¦æ¤ï¼ä½æ¯æ们ä¹æ¨èè¿æ ·åã è¿åå¼æ¯å®é 计ç®ç»æèä¸æ¯è®¡ç®æ¯å¦æåçæ å¿çå½æ°ä¸åæ¤æ¯ä¾çéå¶ãä¸è¬çï¼ä»ä»¬ éè¿è¿åä¸äºæ£å¸¸å¼èå´ä¹å¤çç»ææ¥è¡¨ç¤ºåºéãå ¸åçä¾åæ¯è¿åæéçå½æ°ï¼ä»ä»¬ä½¿ç¨ NULL æè ERR_PTR æºå¶æ¥æ¥åé误ã 第åä¸ç« ï¼ä¸è¦éæ°åæå æ ¸å® å¤´æ件 include/linux/kernel.h å å«äºä¸äºå®ï¼ä½ åºè¯¥ä½¿ç¨å®ä»¬ï¼èä¸è¦èªå·±åä¸äºå®ä»¬ç åç§ãæ¯å¦ï¼å¦æä½ éè¦è®¡ç®ä¸ä¸ªæ°ç»çé¿åº¦ï¼ä½¿ç¨è¿ä¸ªå® #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 类似çï¼å¦æä½ è¦è®¡ç®æç»æä½æåç大å°ï¼ä½¿ç¨ #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f)) è¿æå¯ä»¥åä¸¥æ ¼çç±»åæ£æ¥ç min() å max() å®ï¼å¦æä½ éè¦å¯ä»¥ä½¿ç¨å®ä»¬ãä½ å¯ä»¥èªå·±çç é£ä¸ªå¤´æ件éè¿å®ä¹äºä»ä¹ä½ å¯ä»¥æ¿æ¥ç¨çä¸è¥¿ï¼å¦ææå®ä¹çè¯ï¼ä½ å°±ä¸åºå¨ä½ ç代ç é èªå·±éæ°å®ä¹ã 第åå «ç« ï¼ç¼è¾å¨æ¨¡å¼è¡åå ¶ä»éè¦ç½å¦çäºæ æä¸äºç¼è¾å¨å¯ä»¥è§£éåµå ¥å¨æºæ件éçç±ä¸äºç¹æ®æ è®°æ æçé 置信æ¯ãæ¯å¦ï¼emacs è½å¤è§£é被æ è®°æè¿æ ·çè¡ï¼ -*- mode: c -*- æè è¿æ ·çï¼ /* Local Variables: compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c" End: */ Vim è½å¤è§£éè¿æ ·çæ è®°ï¼ /* vim:set sw=8 noet */ ä¸è¦å¨æºä»£ç ä¸å å«ä»»ä½è¿æ ·çå 容ãæ¯ä¸ªäººé½æä»èªå·±çç¼è¾å¨é ç½®ï¼ä½ çæºæ件ä¸åº 该è¦çå«äººçé ç½®ãè¿å æ¬æå ³ç¼©è¿å模å¼é ç½®çæ è®°ã人们å¯ä»¥ä½¿ç¨ä»ä»¬èªå·±å®å¶ç模 å¼ï¼æè 使ç¨å ¶ä»å¯ä»¥äº§çæ£ç¡®ç缩è¿çå·§å¦æ¹æ³ã 第åä¹ç« ï¼å èæ±ç¼ å¨ç¹å®æ¶æç代ç ä¸ï¼ä½ ä¹è®¸éè¦å èæ±ç¼æ¥ä½¿ç¨ CPU æ¥å£åå¹³å°ç¸å ³åè½ãå¨éè¦ è¿ä¹åæ¶ï¼ä¸è¦ç¹è±«ãç¶èï¼å½ C å¯ä»¥å®æå·¥ä½æ¶ï¼ä¸è¦æ 端å°ä½¿ç¨å èæ±ç¼ãå¦æ å¯è½ï¼ä½ å¯ä»¥å¹¶ä¸åºè¯¥ç¨ C å硬件交äºã èèå»åéç¨ä¸ç¹çå èæ±ç¼ä½ä¸ºç®æçè¾ å©å½æ°ï¼èä¸æ¯éå¤åä¸å®ä»¬çç»èãè®°ä½ å èæ±ç¼å¯ä»¥ä½¿ç¨ C åæ°ã 大èç¹æ®çæ±ç¼å½æ°åºè¯¥æ¾å¨ .S æ件ä¸ï¼å¯¹åº C çååå®ä¹å¨ C 头æ件ä¸ãæ±ç¼ å½æ°ç C åååºè¯¥ä½¿ç¨ âasmlinkageâã ä½ å¯è½éè¦å°ä½ çæ±ç¼è¯å¥æ 记为 volatileï¼æ¥é»æ¢ GCC å¨æ²¡åç°ä»»ä½å¯ä½ç¨åå°± 移é¤äºå®ãä½ ä¸å¿ æ»æ¯è¿æ ·åï¼è½ç¶ï¼è¿æ ·å¯ä»¥éå¶ä¸å¿ è¦çä¼åã å¨åä¸ä¸ªå å«å¤æ¡æ令çå个å èæ±ç¼è¯å¥æ¶ï¼ææ¯æ¡æ令ç¨å¼å·å符串å离ï¼å¹¶åå¨ åç¬ä¸è¡ï¼å¨æ¯ä¸ªå符串ç»å°¾ï¼é¤äº \n\t ç»å°¾ä¹å¤ï¼å¨æ±ç¼è¾åºä¸éå½å°ç¼©è¿ä¸ ä¸æ¡æä»¤ï¼ asm ("magic %reg1, #42\n\t" "more_magic %reg2, %reg3" : /* outputs */ : /* inputs */ : /* clobbers */); 第äºåç« ï¼æ¡ä»¶ç¼è¯ åªè¦å¯è½ï¼å°±ä¸è¦å¨ .c æ件éé¢ä½¿ç¨é¢å¤çæ¡ä»¶ï¼è¿æ ·å让代ç æ´é¾é 读并ä¸é»è¾é¾ä»¥ è·è¸ªãæ¿ä»£æ¹æ¡æ¯ï¼å¨å¤´æ件å®ä¹å½æ°å¨è¿äº .c æ件ä¸ä½¿ç¨è¿ç±»çæ¡ä»¶è¡¨è¾¾å¼ï¼æä¾ç©º æä½çæ¡©çæ¬ï¼è¯æ³¨ï¼æ¡©ç¨åºï¼æ¯æç¨æ¥æ¿æ¢ä¸é¨ååè½çç¨åºæ®µï¼å¨ #else æ åµä¸ï¼ åä» .c æ件ä¸æ æ¡ä»¶å°è°ç¨è¿äºå½æ°ãç¼è¯å¨ä¼é¿å çæä»»ä½æ¡©è°ç¨ç代ç ï¼äº§çä¸è´ çç»æï¼ä½é»è¾å°æ´å æ¸ æ°ã å®å¯ç¼è¯æ´ä¸ªå½æ°ï¼èä¸æ¯é¨åå½æ°æé¨å表达å¼ãèä¸æ¯å¨ä¸ä¸ªè¡¨è¾¾å¼æ·»å ifdefï¼ è§£æé¨åæå ¨é¨è¡¨è¾¾å¼å°ä¸ä¸ªåç¬çè¾ å©å½æ°ï¼å¹¶åºç¨æ¡ä»¶å°è¯¥å½æ°å ã å¦æä½ æä¸ä¸ªå¨ç¹å®é ç½®ä¸å¯è½æ¯æªä½¿ç¨çå½æ°æåéï¼ç¼è¯å¨å°è¦åå®å®ä¹äºä½æªä½¿ç¨ï¼ æ è®°è¿ä¸ªå®ä¹ä¸º __maybe_unused èä¸æ¯å°å®å å«å¨ä¸ä¸ªé¢å¤çæ¡ä»¶ä¸ãï¼ç¶èï¼å¦æ ä¸ä¸ªå½æ°æåéæ»æ¯æªä½¿ç¨çï¼å°±ç´æ¥å é¤å®ãï¼ å¨ä»£ç ä¸ï¼å¯è½çæ åµä¸ï¼ä½¿ç¨ IS_ENABLED å®æ¥è½¬åæ个 Kconfig æ 记为 C çå¸å° 表达å¼ï¼å¹¶å¨æ£å¸¸ç C æ¡ä»¶ä¸ä½¿ç¨å®ï¼ if (IS_ENABLED(CONFIG_SOMETHING)) { ... } ç¼è¯å¨ä¼æ æ¡ä»¶å°å常æ°å并ï¼å°±åä½¿ç¨ #ifdef é£æ ·ï¼å å«ææé¤ä»£ç åï¼æ以è¿ä¸ä¼ 带æ¥ä»»ä½è¿è¡æ¶å¼éãç¶èï¼è¿ç§æ¹æ³ä¾æ§å 许 C ç¼è¯å¨æ¥çåå ç代ç ï¼å¹¶æ£æ¥å®çæ£ç¡® æ§ï¼è¯æ³ï¼ç±»åï¼ç¬¦å·å¼ç¨ï¼ççï¼ãå æ¤ï¼å¦ææ¡ä»¶ä¸æ»¡è¶³ï¼ä»£ç åå çå¼ç¨ç¬¦å·å°ä¸åå¨ï¼ ä½ å¿ é¡»ç»§ç»ä½¿ç¨ #ifdefã å¨ä»»ä½ææä¹ç #if æ #ifdef åçæ«å°¾ï¼è¶ è¿å è¡ï¼ï¼å¨ #endif åä¸è¡çåé¢åä¸ æ³¨éï¼æåºè¯¥æ¡ä»¶è¡¨è¾¾å¼è¢«ä½¿ç¨ãä¾å¦ï¼ #ifdef CONFIG_SOMETHING ... #endif /* CONFIG_SOMETHING */ éå½ Iï¼åè The C Programming Language, 第äºç ä½è ï¼Brian W. Kernighan å Denni M. Ritchie. Prentice Hall, Inc., 1988. ISBN 0-13-110362-8 (软ç®), 0-13-110370-9 (硬ç®). The Practice of Programming ä½è ï¼Brian W. Kernighan å Rob Pike. Addison-Wesley, Inc., 1999. ISBN 0-201-61586-X. GNU æå - éµå¾ª K&R æ ååæ¤ææ¬ - cpp, gcc, gcc internals and indent, é½å¯ä»¥ä» http://www.gnu.org/manual/ æ¾å° WG14æ¯Cè¯è¨çå½é æ ååå·¥ä½ç»ï¼URL: http://www.open-std.org/JTC1/SC22/WG14/ Kernel CodingStyleï¼ä½è greg@kroah.com å表äºOLS 2002ï¼ http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/