Home Map Index Search News Archives Links About LF
[Top Bar]
[Bottom Bar]
[Photo of the Author]
Ismael Ripoll
§@ªÌ²¤¶¡G ¤@¤E¤E¤»¦~©ó Valencia ºî¦X¬ì§Þ¤j¾Ç¨ú±o³Õ¤h¾Ç¦ì¡C ¥Ø«e¥ô¾©ó DISCA¡A ¬°§@·~¨t²Î±M®a¡C ¬ã¨s±MÃD¦³§Y®É¨t²Î±Æµ{ºÞ²z©M§@·~¨t²Îµ¥µ¥¡C ¤@¤E¤E¥|¦~¦¨¬° Linux ªº¤@¥÷¤l¡C ¶Ý¦n¦³¡G Ãkµn¬£·ç¥§´µ¤s¯ß (Pyrenees)¡B ·Æ³·¡B ¥H¤Î·í¤@¦Wºô¸ô¹C«L¡C

»P§@ªÌÁpô

¤º®e¥Ø¿ý¡G
»Å»Åªº Linux §Y®É¨t²Î (KURT)
§Y®É¨t²Î¦³¤°»ò¦nªº¡S
¥i¸ü¤Jªº¼Ò²Õ
§Y®É¨t²Îµ{¦¡
¥ô°È³q°T
µ²½×
°Ñ¦Ò¸ê®Æ

RT-Linux II

[Ilustration]

¤º®eºK­n¡G ³o¬O²Ä¤G½g±´°Q RT-Linux ªº¤å³¹¡A §Ú·|¸ÕµÛ¥H§ó¹ê°ÈªºÆ[ÂI¨Ó»¡©ú RT-Linux¡C ¤£¹L¡A ¦b²`¤J²Ó¸`¤§«e¡A §Ú¥´ºâ¥ý¥Î¤@¬q¤å¦r¸Ñ»¡¤@¤E¤E¤K¦~ªì¡A ­èµo®i¦¨¥\ªº§Y®É§@·~¨t²Îªº¯S¦â¡A ¦W¬° Linux KURT¡C




»Å»Åªº Linux §Y®É¨t²Î (KURT)

¤@¤E¤E¤K¦~ªì¡A ¦³¤@­Ó¥H Linux ¬°°ò¦¤§·sªº§Y®É¨t²Î½Ï¥Í¤F¡C KURT ¬O³n¦¡ªº§Y®É§@·~¨t²Î (soft real-time system)¡A ¤ñ¦p»¡¡A ±Æµ{µ{¦¡·|¸ÕµÛ¥hº¡¨¬¥ô°È (task) °õ¦æ®É©Ò»Ý¨Dªº®É¶¡¡A §Y¨Ï¦³¥ô¦ó¥ô°È°õ¦æ§¹ªº®É¶¡¶W¹L©Ò¹w´Áªº¡A ¤]¤£·|³y¦¨¥ô¦óªº´d¼@¡C KURT ªº§Y®É©Ê¥ô°È¥i¥H¹B¥Î Linux ©Ò¦³ªº¤½¥Îµ{¦¡¡A ³o¤@ÂI«ê¦n¸ò RT-Linux ªº¥ô°È¬Û¤Ï¡C KURT §@·~¨t²Îªº®Ö¤ßµ{¦¡¦³¤@¨Ç§½³¡ªº­×¥¿¡G

  • §ïµ½¤F¨t²Î®ÉÄÁªº®É¶¡¸ÑªR¯à¤O¡C ·íªì¡A ¦b Linux-i386 ªº¦~¥N¡A ¨t²Î®ÉÄÁªº¤¤Â_ÀW²v¬O¨C¬í 100 ¦¸¡A ®Ö¤ßµ{¦¡´N¬O¥Î³o­Ó®É¶¡¤À¬q¨Ó±±¨î CPU ©M¶q´ú®É¶¡ªº¡C KURT ©M RT-Linux ¤@¼Ë¡A ±Ä¥Î¬Û¦Pªºµ¦²¤¨Ó³B²z®É¶¡ªº°ÝÃD¡C KURT ´À®ÉÄÁ´¹¤ù (8254) ³]­p¤Fµ{¦¡¡A ¨Ï±o¨t²Î®ÉÄÁªº¤¤Â_¡A ¦¨¤FÀH¶ÇÀH¨ì¡A ¤@©I´N¦³¡A ¦Ó«D©T©w¤£Åܪº©P´Á¤F¡C ³o»ò¤@¨Ó¡A ¤d¤À¤§¤@¬íªº®É¶¡¸ÑªR«×¡A ´N¦A¤]¤£¬O¹Ú¤F¡C
  • ±Æµ{µ{¦¡¤]¤w¸g­×§ï¹L¤F¡G ±Ä¥Î·sªº±Æµ{µ¦²¤¡A SCHED_KURT¡C °£¦¹¤§¥~¡A Linux ªº®Ö¤ßµ{¦¡¤w¸g¹ê§@¤F¤@³¡¥÷¡A ¬O POSIX ©w¸qªº¼Ð·Ç¡G SCHED_FIFO¡B SCHED_RR ©M SCHED_OTHER¡C
  • ·sªº¨t²Î©I¥s¨ç¼Æ¤]¤w¸g¥[¤J KURT¡A ¥H«K©ó§Q¥Î³o­Ó·sªº§Y®É§@·~¨t²Î¤§¾÷¯à¡C

§Y®É¨t²Îªº¥ô°È³£¬O°ÊºA¸ü¤Jªº¼Ò²Õ¡C

KURT ³Ì¨ã¯S¦âªº«K¬O±Æµ{µ¦²¤¡C ±Æµ{µ{¦¡¬O´`Àôªº¡A ³oºØ«¬¦¡ªº±Æµ{µ{¦¡¡A ¬O¹B¥Î¤@±i¦W¬°­pµeªí (plan) ªºªí®æ¡A ¨ÓÀx¦s©Ò¦³¶i¤J±Æµ{ªº¥ô°Èªº°Ê§@¡G ±Ò°Êªº®É¨è¡B ¹w³Æ°õ¦æªº¥ô°È¡B ¥ô°Èªº©µ®Éµ¥µ¥¡C ³o±iªí®æ¶}¾÷®É´N·|«Ø¦n¡A µ¥¨ì¥ô°È­n°õ¦æ®É¡A ±Æµ{µ{¦¡ªº¤u§@¡A ´N¶È³Ñ¤U¨Ì§Ç¤@¶µ¶µÅª¨úªí¤¤ªº¸ê®Æ¤F¡C ·í±Æµ{µ{¦¡Åª¨ìªí¤¤ªº§ÀºÝ®É¡A ±Æµ{µ{¦¡·|¦^¨ìªí¤¤ªº³Ì¶}ÀY³B¡A Ä~Äò³B²z¥ô°Èªº°õ¦æ¤u§@ ¡X¡X ¤]´N¬O³o¼Ë¡A ¤~§â³oºØ±Æµ{µ{¦¡¡A ©R¦W¬°´`Àô±Æµ{µ{¦¡ (cyclic scheduler)¡C ´`Àô±Æµ{µ{¦¡¦³½Ñ¦hªºÀuÂI¡G

  • ®e©ö¹ê§@¡C

  • ¬Û·í¦³®Ä²v¡C

  • ­pµeªí¤@¥¹«Ø¦n¤§«á¡A ¤@­Ó¨t²Î´N¥i¥H«Ü§Ö¦a¹ê§@¥X¨Ó ¡]¦³¤@¨Ç¬ã¨s¤H­ûÁÙ°í«H¡A ³o¬O°ß¤@«OÃÒ STR ±o¥H¦Ê¤À¦Ê¥¿½T°õ¦æªº¤èªk¡^¡C

³Ì¥D­nªº§xÃøÂI¡A ´N¦b©ó«ç¼Ë¥h»s§@­pµeªí¤F¡C ÁÙ¦³¡A ¨C¦¸¥u­n¦³¥ô¦ó¤@¶µ¥ô°Èªº°Ñ¼Æ°µ¤F­×¥¿¡A ´N¥²¶·­««Ø­pµeªí¡F ¦P®É¡A Àx¦s­pµeªí©Ò»Ýªº°O¾ÐÅé¤]¤jªºÅå¤H¡C

§Y®É¨t²Î¦³¤°»ò¦nªº¡S

¤]³\¦h¼Æ¤H³£¥H¬°¡A §Y®É¨t²Îªº§Þ³N¥u¯àÀ³¥Î¦b NASA¡A ©Î¬O¾É¼u¡B ¯èªÅ¾¹¤§Ãþªº»â°ì¸Ì¡C ÁöµM¡A ¦b¦h¦~¥H«e¡A ³oªº½T¬O­Ó¤£§é¤£¦©ªº¨Æ¹ê¡A µM¦Ó¡A ¥@¨Æ­ì¥»´N·É®áÃø®Æ¡A ªñ¦~¨Ó¥Ñ©ó¸ê°T¨t²Î©M¹q¤lªº¾ã¦XÀ³¥Î¡A ¥¿³v¨B¤j¶q¦a¤Þ¶i¤@¯ë¤Hªº¤é±`¥Í¬¡¤¤¡A±¡¶Õ¤w¸g¦³¤F§ïÅÜ¡C ©M§Ú­Ì¤é±`¥Í¬¡®§®§¬ÛÃö³Ìª½±µªºÃÒ¾Ú¡A ´N¬O¹q¶Ç³q°T (telecommunications) ©M¦h´CÅ骺À³¥Î»â°ì¡A ¤ñ¦p»¡¡A ¦pªG§Ú­Ì·Q­nÅý¹q¸£¡A ¥i¥H­«Âм½©ñ¤@­ÓÀx¦s©óµwºÐ¸Ìªº­µ®ÄÀÉ¡A ³B²z­µ®Äªºµ{¦¡´N±o¤£Â_¦a ¡]©ÎªÌ§ó¦nªº¡A ¬O©T©w©P´Áªº¡^ ¥hµwºÐ¸ÌŪ¨úÀɮ׸ê®Æ¡A ¸ÑÀ£ÁY¡A µM«á§â¼Æ¦ì¸ê®Æ°e¥X¥hµ¹­µ®Ä¥d¡C °²¦p»¡¡A ¦P¤@®É¶¡¡A §Ú­Ì¥¿¦b¾Þ§@¤@®MÀ³¥Î³nÅé¡A ¥i¯à¬O¤å®Ñ³B²zµ{¦¡¡A ©Î¬O¥¿¦b½sĶ Linux ªº®Ö¤ßµ{¦¡¡F ÅãµM¡A CPU ³B²z¾¹·|¥H©P´Á´`Àôªº¤ù¬q®É¶¡¡A ¨Ó³B²z¨ä¥Lªº¥ô°È¡C ¦pªG¤£©ñ­µ®Ä¡A §ï¦b¿Ã¹õ¤W­«Âм½©ñ¼v¹³¡A ·L³B²z¾¹¤À¬q³B²zªºµ²ªG¡A ¼v¹³«K·|¦³¶¡·²©Êªº°±¹y¡C ³oºØ¨t²Î«K¬O©Ò¿×ªº¡u³n¦¡§Y®É¨t²Î¡v ¡]°õ¦æ´Á¶¡¦³¤¤Â_ªº²{¶H¨Ã¤£·|³y¦¨¤°»ò¥¨¤jªº¨a®`¡A ¤£¹L¡A ³o¼Ëªº¨t²Îªº½T·|­°§CªA°Èªº«~½è¡^¡C

RT-Linux ªºÀ³¥Îµ{¦¡¡A ©M¤@¯ë¥¿±`ªº§Y®ÉÀ³¥Îµ{¦¡¤j²§¨ä½ì¡C ¹ï RT-Linux ¦Ó¨¥¡A §Ú­Ì¥i¥H¥þµM´x±± PC ªº¹B§@ ¡]§Ú·|»¡ PC ¦Ó¤£¬O¹q¸£¡A ¬O¦]¬°¨ì¥Ø«e¬°¤î¡A °£¤F·L¹q¸£¤§¥~¡A RT-Linux ÁÙ¨S¦³²¾´Ó¨ì¨ä¥LºØªº¾÷¾¹¬[ºc¤W¥h¡^¡A ¦p¦P¹L¥hªº MSDOS ¤@¯ë¡C ·í¤@­Ó§Y®É¨t²Îªº¥ô°È¥æµ¹ CPU ¥h°õ¦æ®É¡A ³o­Ó°õ¦æ¤¤ªº¥ô°È¬O¥i¥H¥h¦s¨ú PC ¤W©Ò¦³ªº¦ì§}ªúªº¡A ¨Ò¦p´Ó¤J¤¤Â_ªA°È±`¦¡¡A ¼È®ÉÃö³¬¤¤Â_ªA°È±`¦¡ªº¥\¯àµ¥µ¥¡C ´«¥y¸Ü»¡¡A §Ú­Ì¥i¥H"ºR·´"³o®M¨t²Î¡A ¦p¦Pµøµ¡¨t²Î¨º»òªº¤£³ô¤@À»¡C ¦ý¬O¡A ¸Ü¤S»¡¦^¨Ó¡A ³oºØ¤è«K¤§ªù¡A ¹ï©ó«Ü³ßÅw¼g¨Çºë¥©ªº¤pµ{¦¡¡A µ¹¦Û¤v¹q¸£¥h¶]ªº¤H¦Ó¨¥¡A «K¨ã¦³¬Û·í¤jªº¾y¤O¤F¡C

¥i¸ü¤Jªº¼Ò²Õ

­n·QÁA¸Ñ RT-Linux¡A ÁÙ¦³¨ã³Æ¯à¤O¥h¨Ï¥Î RT-Linux¡A ¦³Ãö Linux °ÊºA¸ü¤J¼Ò²ÕªºÆ[©À¡A ¬O¦³¥²­nª¾¹Dªº¡C Matt Welsh ¤w¸g¼g¤F§¹¾ãªº¤å¥ó¡A ¨Ó¸Ñ»¡¼Ò²Õ©Ò¦³ªº²Ó¸`¡C

¼Ò²Õ¨ì©³¬O¤°»ò¡S

¤j³¡¥÷ªº UNIX ¨t²Î¦s¨úµwÅé®É¡]¦ì§}ªú¡B°O¾ÐÅé¡B¤¤Â_µ¥µ¥¡^¡A ³£¬O¸g¥Ñ¯S§OªºÀɮרӳB²zªº¡A ³q±`¤]³£¬O°ß¤@ªº¤èªk¡C ¨t²Î¦w¸Ë®É¡A ·|¨Æ¥ý¦w¸Ë¦n¨C¤@ºØ¶gÃä³]³Æ©Ò»ÝªºÅX°Êµ{¦¡¡C ¤£¹L¡A ¦³«Ü¦h¤£¿ùªº®ÑÄy³£¦³±Ð§Ú­Ì«ç»ò¥h¼g³]³ÆÅX°Êµ{¦¡¡A ³o±`±`¬O¬JµL²á¤S¤¾ªøªº¤u§@¡A ¦]¬°§Ú­Ì±o¼g¥X¬°¼Æ¤£¤Öªº¨ç¼Æ¡A §âÅX°Êµ{¦¡©M¨t²Î³sµ²°_¨Ó¡C

¼Ò²Õ¥i¥H»¡¬O"§@·~¨t²Îªº¤ù¬qµ{¦¡½X"¡A ¥i¥H¦b°õ¦æ´Á¶¡ÀH®É¥[¤J©Î¬O©âÂ÷¥X¨Ó¡C °²³]¦³¤@¤äµ{¦¡ªº­ì©l½X¡A ¤À§OÀx¦s¦b¦U­Ó¤£¦PªºÀɮ׸̡A ­n®³¨Ó½sĶ¡A ­º¥ý¡A ¨C­Ó³æ¤@ªºÀÉ®×·|¥ý³Q°µ¦¨ ".o" ¤§¥ØªºÀÉ¡A µM«á¡A ©Ò¦³ªº¥ØªºÀɦA³sµ²¦¨³æ¤@ªº¥i°õ¦æÀÉ¡C °²³]¥ØªºÀɤ¤¡A ¦³¤@­ÓÀɮקt¦³ main ³o­Ó¨ç¼Æ¥i¥H°õ¦æ¡A ¨º»ò§@·~¨t²Î«K¥i¥H±N³o­ÓÀɮ׸ü¤J°O¾ÐÅ餤°õ¦æ¡A ¨Ã¥B¦b»Ý­nªº®É­Ô¡A §â¨ä¥Lªº¥ØªºÀɳsµ²¶i¨Ó¤@°_°õ¦æ¡C ·íµM¡A ®Ö¤ß¥»¨­¦ÛµM¦³¯à¤O³B²z³o¼Ëªº°ÝÃD¡C ¨Æ¹ê¤W¡A ·í Linux ¶}¾÷¤§«á¡A ¤]¥u¦³°õ¦æÀÉ vmlinuz ¸ü¤J°O¾ÐÅé¸Ì¡A vmlinuz §t¦³ Linux ®Ö¤ß¤£¥i©Î¯Êªº¤¸¥ó¡A «Ý¨t²ÎÂର°õ¦æ´Á¶¡®É¡A ®Ö¤ß«K¥i¨Ì»Ý¨D¨Ó¸ü¤J©Ò»Ýªº¼Ò²Õ¡A ©Î¬OÄÀ©ñ¤£»Ý­nªº¼Ò²Õ¡C

¹ï Linux ®Ö¤ß¦Ó¨¥¡A ¼Ò²Õ¬O¥i¦³¥iµLªº¯S¦â¡C ³o¶µ¯S¦â¥²±o¦b½sĶ®Ö¤ß®É¡A ¿ï¾Ü¾A·íªº¿ï¶µ¤~±o¥H³º¥þ¥\¡C ´N§Ú©Òª¾¹Dªº¡A ©Ò¦³µo¦æ¨t²Îªº®Ö¤ßµ{¦¡¡A ³£¬O¥H¼Ò²Õ¤Æ©w¬°¹w³]¿ï¶µªº¡C

§Ú­Ì¬Æ¦Ü©ó¥i¥H´À¨t²Î³]­p·sªº¼Ò²Õ¡A ¨Ã¥Ñ®Ö¤ß¸ü¤J°õ¦æ¡A ¦Ó¤£¥Î­«·s½sĶ¨t²Î¡A ¤]¤£¥Î­«·s±Ò°Ê¨t²Î¡C

·í¤@¼Ò²Õ¸ü¤J®Ö¤ß®É¡A «K¦¨¤F§@·~¨t²Îªº¤@³¡¥÷¡A ¦]¦¹¡G

  • ³o­Ó¼Ò²Õ¥i¥H¨Ï¥Î®Ö¤ßµ{¦¡¤¤©Ò¦³ªº¨ç¼Æ¡A ¦Ó¥B¥i¥H¦s¨ú©Ò¦³ªºÅܼƩM¸ê®Æµ²ºc¡C

  • ³o­Ó¼Ò²Õ·|¥H³B²z¾¹³Ì°ª¼h¦¸ªºÅv¦ì¨Ó°õ¦æ¡C ´N i386 ªº¬[ºc¨ÓÁ¿¡A ´N¬O²Ä 0 ¼hªºÀô (ring level 0)¡F ³o»ò¤@¨Ó¡A ³o­Ó¼Ò²Õ´N¥i¥H°w¹ï I/O¡A °µ¦U¦¡¦U¼Ëªº¦s¨ú°Ê§@¡A ¨Ã°õ¦æ¤@¯ëµ{¦¡©ÒµLªk°õ¦æªº«ü¥O¡C

  • ¼Ò²Õªºµ{¦¡½X©M¸ê®Æ¬q¡A ³£¬Oª½±µ¬M®g¨ì¹êÅ骺°O¾ÐÅé¤W¥h¡A ¤]´N¬O»¡³oºØ¼Ò²Õ¤£¥i¯à°µ"¤À­¶ (paging)" ªº°Ê§@¡C ³o»ò»¡¨Ó¡A ¦b¼Ò²Õ°õ¦æ´Á¶¡¡A ´N¤£¥i¯à·|²£¥Í¤À­¶¿ù»~ªº°ÝÃD¤F¡C

¦p¦P§Ú­Ì©Ò¨£ªº¡A °ÊºA¸ü¤J¼Ò²Õ¤w¸g¦³¤@¨Ç§Y®É¨t²Îµ{¦¡ªº¯SÂI¡G °ÊºA¸ü¤J¼Ò²Õ¡A ·|ÁקK¥Ñ¤À­¶¿ù»~©Ò³y¦¨ªº®É¶¡©µ¿ð¡A ¦Ó¥B°ÊºA¸ü¤J¼Ò²Õ¡A ¥i¥H¦s¨ú©Ò¦³ªºµwÅé¸ê·½¡C

«ç»ò«Ø¼Ò²Õ¡S «ç»ò¥Î¡S

¼Ò²Õ¥i¥H "C »y¨¥" ¨Ó¼g¡C ³o¸Ì¦³­Ó¤p¤p¼Ò²Õªº¨Ò¤l ¡]­n°õ¦æ¤U­±©Ò´£¨ìªº©R¥O¡A³Ì¦n¬O¥H su¡Broot ªº¨­¥÷µn¿ý¨t²Î¡^¡G

example1.c

  #define MODULE
  #include <linux/module.h>
  #include <linux/cons.h>
  static int output=1;

  int init_module(void) {
    printk("Output= %d\n",output);
    return 0;
  } 
  void cleanup_module(void){   
    printk("Adiós, Bye, Chao, Ovuar, \n");
  }

¥H¤U¤@¦æªº°Ñ¼Æ¨Ó½sĶ example1.c¡G

# gcc -I /usr/src/linux/include/linux -O2 -Wall -D__KERNEL__ -c example1.c

¿ï¶µ -c ¬O­n¨D gcc ¦b²£¥Í¥ØªºÀɤ§«á´N°±¤U¨Ó¡A ¤£­n¦A°µ³sµ²ªº°Ê§@¡C ³Ì«áªºµ²ªG¬O¤@­Ó¥ØªºÀÉ¡A example1.o¡C

®Ö¤ßµ{¦¡¯Ê¤Ö¼Ð·Ç¿é¥X¨ç¼Æ¡A ¦]¦¹§Ú­Ì¤£¥i¥H¥Î printf() ³o­Ó¨ç¼Æ¡A ¦Ó­n¥H®Ö¤ßµ{¦¡©Ò´£¨Ñªº printk() ¨ç¼Æ¨Ó¥N´À¡C printk() ©M printf() ´X¥G¨S¤°»ò¨â¼Ë¡A °ß¤@ªº®t§O¬O printk() ·|§â¿é¥Xªºµ²ªG¡A °e¨ì®Ö¤ßµ{¦¡ªºÀô½w½Ä°Ï (ring buffer) ¸Ì¡C ³o­Ó½w½Ä°Ï¬O¨t²Î©Ò¦³°T®§¶°¤¤ªº¦a¤è¡A ´N¹³¶}¾÷®É©Ò¨£¨ìªº°T®§¡A ³£¥i¥H¦b³o­ÓÀô½w½Ä°Ï¸Ì§ä¨ì¡C ¥ô¦ó®É­Ô¡A §Ú­Ì³£¥i¥H¥Î dmseg ©R¥O¬d¬Ý½w½Ä°Ïªº¤º®e¡A ©Î¬Oª½±µÀËÅç /proc/kmsg ³o­ÓÀɮסC

ª`·N¨ì³o­Ó¼Ò²Õ¸Ì¨Ã¨S¦³ main() ¨ç¼Æ¡A ¤Ï¦Ó¦³­Ó¤£±a¥ô¦ó°Ñ¼Æªº init_module() ¨ç¼Æ¡C cleanup_module() ¬O³Ì«á¤@­ÓÄÀ©ñ¼Ò²Õ«e¡A ©Ò¥²¶·©I¥sªº¨ç¼Æ¡C insmod ¬O¥Î¨Ó¸ü¤J¼Ò²Õ¡A µM«á°õ¦æ¼Ò²Õªº¡C

  # insmod example1.o

²{¦b¡A §Ú­Ì¤w¸g¦w¸Ë¦n example1 ¼Ò²Õ¤F¡A ¦Ó¥B¤]°õ¦æ¤F example1 ªº init_module() ¨ç¼Æ¡C ­n¬Ýµ²ªG¡A ½Ð¥´¤U¦Cªº©R¥O¡G

  # dmesg | tail -1
  Output= 1   

©R¥O lsmod ·|¦C¥X·í«e©Ò¦³¸ü¤J®Ö¤ß¤¤ªº¼Ò²Õ¡G

# lsmod
Module    Pages   Used by:
example1      1          0
sb            6          1
uart401       2  [sb]    1
sound        16  [sb uart401]  0 (autoclean) 

³Ì«á©O¡A§Ú­Ì¥Î rmmod ¨ÓÄÀ©ñ¼Ò²Õ¡G

  # rmmod example1
  # dmesg | tail -2
  Output= 1
  Adiós, Bye, Chao, Orvua,     

dmesg Åã¥Ü¤F¨ç¼Æ cleanup_module() ¤w¸g°õ¦æ¤F¡C

²{¦b¡A §Ú­Ì¥u®tÁÙ¤£ª¾¹D«ç»ò§â°Ñ¼Æ¶Çµ¹¼Ò²Õ¤F¡C ³o­Ó¤èªk¥X©_ªºÂ²³æ¡A ¥u­n«ü©w¼Æ­Èµ¹¾ãÅéÅܼơA ¦AÂÇ¥Ñ insmod §â°Ñ¼Æ¶Ç»¼µ¹¼Ò²Õ´N¦æ¤F¡C ¨Ò¦p¡G

  # insmod ejemplo1.o output=4
  # dmesg | tail -3
  Output= 1
  Adíos, Bye, Chao, Orvua,
  Output= 4                

²{¦b¡A ¼Ò²Õ¤j¤j¤p¤pªº¨Æ±¡¡A ¸Óª¾¹Dªº³£ª¾¹D¤F¡C ¦^ RT-Linux ¤F§a¡I

§Aªº²Ä¤@­Ó§Y®É¨t²Îµ{¦¡

­º¥ý¡A °O¦í¤@ÂI¡A ­n·Q¥Î RT-Linux¡A ´N±o¹w¥ý·Ç³Æ¦n Linux ªº®Ö¤ßµ{¦¡¡A ¥H¤ä´©§Y®É¨t²Î¼Ò²Õ¡C ³o¤@³¡¥÷ªº»¡©ú¡A ¸Ô¨£²Ä¤@½g¤å³¹¡C

RT-Linux ¥i¥H¦³¨âºØ¾Þ§@¤èªk¡G

  1. ·í§@¨å«¬ªº§Y®É¨t²Î¨Ó¥Î¡A µ{¦¡ªºÀu¥ýÅv©ó°õ¦æ´Á¶¡¤£ÅÜ¡A ±Æµ{µ{¦¡·|¨Ì¾Ú¨Æ¥ý³]©w¦nªºÀu¥ýÅv¶¶§Ç¡A ¨Ó°õ¦æµ{¦¡¡C

  2. ·í§@¯Â PC ¨Ó¥Î¡A ¦³ÂI¹³ DOS ªº¼Ë¤l¡G ¸É®»¤¤Â_°T¸¹¡A §¹¥þ´x´¤¹q¸£ªº¹B§@¡C

³o¤@¦¸§Ú·Q¥ý°Q½×¦b²Ä¤@ºØ±¡ªp¤U¡A «ç¼Ë§â RT-Linux ·í§@§Y®É¨t²Î¨Ó¨Ï¥Î¡C »Õ¤U§Y±N­n¬Ý¨ìªºµ{¦¡½d¨Ò¡A ¥»¨­¨Ã¨S¦³¤°»ò"¥Î³~"¡A ¶È¶È¬O³]©w¤F¤@­Ó§Y®É¨t²Îªº¥ô°È¦Ó¤w¡]¤@­Ó²³æªº°j°éµ{¦¡¡^¡G

example2.c
  #define MODULE
  #include <linux/module.h>
  #include <linux/kernel.h>
  #include <linux/version.h>
  #include <linux/rt_sched.h>
  RT_TASK task;
	  
  void fun(int computo) {
    int loop,x,limit;
    limit = 10;
    while(1){
      for (loop=0; loop<computo; loop++)
        for (x=1; x<limit; x++);
      	
      rt_task_wait();
    }
  }
  
  int init_module(void) {

    RTIME now = rt_get_time(); 

    rt_task_init(&task,fun, 50 , 3000, 1);
    rt_task_make_periodic(&task,
          now+(RTIME)(RT_TICKS_PER_SEC*4000)/1000000,
	 (RTIME)(RT_TICKS_PER_SEC * 100)/1000000);
    return 0;
  }

  void cleanup_module(void){
    rt_task_delete(&task);
  }

¦P¼Ëªº¡A¥H¤U¦Cªº©R¥O¨Ó½sĶ example2.c¡G

# gcc -I /usr/src/linux/include/linux -O2 -Wall -D__KERNEL__ -D__RT__ -c example2.c

¬JµM¬O¼Ò²Õ¡Aµ{¦¡ªº°_ÂI¦ÛµM¬O¨ç¼Æ init_module()¤F¡C³o­Ó¼Ò²ÕÀY¤@¥ó°µªº¨Æ´N¬O¥hŪ·í«eªº®É¶¡µM«á§â®É¶¡Àx¦s¦b¤@­Ó§½³¡ÅܼƸ̡Crt_get_time()¨ç¼Æ·|¶Ç¦^±q¶}¾÷°_©Ò¸g¹Lªº®É¶¡­È RT_TICKS_PER_SEC ¡]¥Ø«e¨ÓÁ¿¡A RT_TICKS_PER_SEC¬O1.193.180¡A¸ÑªR«×¬O0.838 micro-seconds¡^¡C °õ¦æ¨ìrt_task_init()®É¡A"task" structure·|¶i¦æªì­È³]©w¡A¦ýÁÙ¨S¶}¶]¡C ³o­Óªº¥ô°Èªº¥Dµ{¦¡¬Ofun()¡A²Ä¤G­Ó°Ñ¼Æ¡C¤U¤@­Ó°Ñ¼Æ¬O·í·stask­n¶}©l°õ¦æ®É¡A­n¶Ç»¼µ¹·staskªº¸ê®Æ­È¡C­nª`·N¨ìfun()­nªº¬Oint«¬ºAªº°Ñ¼Æ¡C¤U¤@­Ó°Ñ¼Æ¬Otask°ïÅ|ªÅ¶¡ªº¤j¤p¡A³o¬O¦]¬°¨C¤@­Ótask³£¦³¥L¦Û¤vªº°õ¦æºü¡]thread of execution¡^¡A¦]¦¹¨C­Ótask³£»Ý­n¦³¦Û¤vªº°ïÅ|ªÅ¶¡¡C³Ì«á¤@­Ó°Ñ¼Æ¬OÀu¥ýÅv¡F´N³o­Óµ{¦¡¨Ò¨ÓÁ¿¡A¥u¦³¤@¥ó¥ô°È¦b¨t²Î¤W°õ¦æ¡A§Ú­Ì¥i¥H³]©w¥ô¦ó©Ò­nªº¼Æ­È¡C

rt_task_make_periodic()·|§â¥ô°ÈÂà´«¦¨´`Àô¦¡¥ô°È¡C³o»Ý­n¨â­Ó®É¶¡°Ñ¼Æ¡A²Ä¤@­Ó¬O°O¿ý¥ô°È²Ä¤@¦¸³Q±Ò°Êªºµ´¹ï®É¶¡¡A¦Ó²Ä¤G­Ó¬O³sÄò±Ò°Êªº¥ô°È¤§¶¡¡A±q²Ä¤@­Ó¥ô°È°_ºâªº®É¶¡¶¡¹j¡C

³o­Ó§Y®É¨t²Î¥ô°È¡]´N¬O¨ç¼Æfun()¡^¬O¤@­ÓµL½aªº°j°é¡A¥u°µ¨â¥ó¨Æ±¡¡G¤@¬O®ö¶O®É¶¡ªº°j°é¡A¤G¬O©I¥s rt_task_wait()¡Crt_task_wait()¬O¥Î¨Ó¼È®É¤¤¤î¥ô°È°õ¦æªº¨ç¼Æ¡Aª½¨ì¤U¤@¦¸ªº±Ò°Ê®É¶¡¡]activation time¡^¨ì¤F¬°¤î¡C±µµÛ¥ô°È·|±qºò±µ¦brt_task_wait()«á­±ªº±Ô­z¶}©l°õ¦æ¡CŪªÌÀ³·í©úÁA¡A´`Àô¦¡ªº¥ô°È¨Ã«D¨C¦¸±Ò°Ê®É³£·|±qÀY¶}©l°õ¦æµ{¦¡¡A¦Ó¬O¦Û¦æ¼È°±°õ¦æ¡A¨Ãµ¥«Ý¤U¤@¦¸ªº±Ò°Ê®É¶¡¨ì¨Ó¡C³oºØ³]­p¾÷¨î·|Åý¥ô°È¶È¦b²Ä¤@¦¸©I¥s®É°õ¦æ¤@¦¸ªì­È³]©wªº¤u§@¡A¦]¬°¥ô°È¤£·|±qÀY¶}©l°õ¦æ¡C

°õ¦æ example2 ¤§«e¡A ¶·¥ý¦w¸Ë¦n rt_prio_sched ¼Ò²Õ¡A ³o¬O¦]¬° example2 »Ý­n rt_task_make_periodic()¡B rt_task_delete() ©M rt_task_init() ³o¨Ç¨ç¼Æ¡C ¨ç¼Æ rt_get_time() ¨Ã¨S¦³¥]§t¦b³o­Ó¼Ò²Õ¸Ì­±¡A ³o­Ó¨ç¼Æ¦s©ñ¦b Linux ªº®Ö¤ßµ{¦¡¤¤¡A ¦]¦¹¨Ã¤£»Ý­n¦h°µ¦w¸Ëªº°Ê§@¡C

  # modprobe rt_prio_sched
  # insmod ./example2.o

¤w¦³ªº rt_prio_sched¡A ¬O¨t²Î¥»¨­ªº¼Ò²Õ¡C ³o­Ó¼Ò²Õ·|¦b Linux ®Ö¤ß½sĶ´Á¶¡«Ø¥X¨Ó¡A µM«á«þ¨©¨ì /var/modules/2.0.33/ ³o­Ó¥Ø¿ý©³¤U¡C §Ú­Ì¨Ï¥Î modprobe ³o­Ó©R¥O¡A ­ì¦]¬O³o¬O­Ó¤ñ¸û²³æªº¤u¨ã¡A ´N¸ü¤J¼Ò²Õ¨ÓÁ¿¡]modprobe·|¦b¼Ò²Õªº¥Ø¿ý¤¤·j´M±ý¸ü¤Jªº¼Ò²Õ¡^¡C ¡]°Ñ¨£ modprobe(1)¡^¡C

­Õ­Y©Ò¦³ªº¨BÆJ³£«Ü¶¶§Q¡A ¥u­n¦A¥[ lsmod ©R¥O¡A ´N¥i¥H¬Ý¨ì¨â­Ó¼Ò²Õ³£¥¿½T¦a¸ü¤J¤F¡C

¶â¡A ¨ì¤F³o­Ó¶¥¬q¡A »Õ¤U¤w¸g¦³¤F¤@­Ó§Y®É¨t²Îµ{¦¡¦b¨t²Î¤W¶]¤F¡C §A¦³¨S¦³µo²{¤°»ò¯S§Oªº¨Æ±¡µo¥Í¡S °²¦p³B²z¾¹¥»¨­´N¶]±o¤ñ¸ûºC¡A §A·|µo²{ Linux ¶]±o¤ñ¥­±`ÁÙ­nºC¡C §A¥i¥H¸ÕµÛ¥h¼W¥[ fun() ¨ç¼Æ¤¤¡A ¤º³¡°j°éªº¥æ´À¦¸¼Æ¡A ¥u­n§ïÅÜ rt_task_init() ¨ç¼Æªº²Ä¤T­Ó°Ñ¼Æ«K¥i¥H¤F¡C §Ú«ØijŪªÌ¤£§«¶]¤@¤U ico¡A ¬d¬d¬Ý³B²z¾¹¯à³Ñ¾lªº®É¶¡¤Ö¤F¦h¤Ö¡C ¦]¬°§Y®É¨t²Îµ{¦¡©Ò¯Ó¥Îªº®É¶¡¡A ·|³y¦¨³B²z¾¹¹³¬O³t«×ÅܺC¤Fªº¡A Linux ·|¥H¬°©Ò¦³ªºµ{§Ç¡A ©Ò»Ý¨Dªº°õ¦æ®É¶¡¶W¹L­ì¥»©Ò»Ýªº¡C ¦pªG­pºâ¥X¨Óªº®É¶¡ ¡X¡X ´N¬O°õ¦æ©Ò¦³°j°é©Ò»Ýªº®É¶¡ ¡X¡X ¤j¹L 100 ²@¬í (microseconds)¡A Linux ´N·|"±¾"¦b¨ºÃä¤F¡C ¦]¬° Linux ¬O­I´ºµ{¦¡¡A ¦Ó³o­Ó§Y®É¨t²Î¥ô°È·|¯ÓºÉ©Ò¦³ªº®É¶¡¡C ¨Æ¹ê¤W¡A Linux ¨Ã¨S¦³±¾±¼¡A Linux ¥u¬O±o¤£¨ì³B²z¾¹ªº®É¶¡½}¤F¡C

¥ô°È³q°T

RT-Linux ¥u¦³¤@ºØ¥ô°È³q°Tªº¤èªk¡G Real-Time FIFO¡C ³o­Ó¤èªk«ÜÃþ¦ü UNIX ªº PIPEs¡A ¶È¥H¸ê®Æ¬y¨Ó³q°T¡A ¦Ó¨S¦³¥ô¦óªº¸ê®Æµ²ºc¡C FIFO ¬O¤@¶ô©T©w¤j¤pªº½w½Ä°Ï¡A ¥Î¨ÓŪ¼g¸ê®Æ¤§¥Î¡C

±Ä¥Î FIFOs ¥i¥HÅý§Y®É¨t²Î¡A ¥ô°È¶¡ªº¤º³¡³q°TÁÍ©óí©w¡F ¹ï©ó¤@¯ë Linux ªº¥ô°È¦Ó¨¥¡A ¤]¦P¼Ë¾A¥Î¡C

±q¥¿±`µ{§Ç (process) ªº²´¥ú¨Ó¬Ý¡A FIFO ¬O¤@­Ó¯S®í¦r¤¸ªºÀɮסC ¤@¯ë¦Ó¨¥¡A ·|¬O /dev/rtf0¡B /dev/rtf1 µ¥µ¥½Ñ¦p¦¹Ãþªº¡C ³o¨ÇÀɮר䣬O Linux ­ì¦³ªº¡A ©Ò¥H¥²¶·ÃB¥~¦A«Ø¡C ¤èªk¦p¤U¡G

# for i in 0 1 2 3; do mknod /dev/rtf$i c 63 $i; done

¦pªG FIFOs ªº»Ý¨D¶W¹L¤W¦C©ÒÁ|ªº¡A ¨ä¥Lªº FIFO ´N¥i¥H¨Ì¼Ëµe¸¬Äª¦a»s§@¥X¨Ó¡A ¦p rtf4¡B rtf5 µ¥µ¥¡C ³o¨Ç¯S®íÀɮתº§@¥Î¡A ´N¦n¹³handlerªº¤¶­±¤@¼Ë¡A ¦ý¬O¦pªG handler ¤£¦s¦b¡A ³o¨Ç¯S®íÀÉ®×´N¤@ÂI»ù­È¤]¨S¦³¤F¡C ¨Æ¹ê¤W¡A ¦pªG§@·~¨t²Î¨S¦³¬Û¹ïÀ³ªº handler¡A ¤@©w¨S¦³¿ìªk¦¨¥\¦a¶}±Ò³o¨Ç¯S®íÀɮסC

DrawObject

³B²z FIFOs ªºÀɮשM¥¿±`ªºÀɮרS¤°»ò¨â¼Ë (open¡B read/write¡B close)¡C ¦pªG Linux ¥¿±`ªºµ{§Ç (process) ­n¨Ï¥Î FIFOs¡A ­º¥ý¡A §Y®É¨t²Îµ{¦¡±o¥ý«Ø¥ß¬Û¹ïÀ³ªº FIFO¡C

±q§Y®É¨t²Î¥ô°Èªº²´¥ú¨Ó¬Ý¡A FIFOs ¬O¸g¥Ñ¯S©w¨ç¼Æ¨Ó¨Ï¥Îªº¡G

  • rt_create(unsigned int fifo, int sise)¡G «Ø¥ß¤@­Ó FIFO¡A ½w½Ä°Ï¤j¤p¬° size¡C ±q³o­Ó®É­Ô°_¡A ¤@ª½¨ì FIFO ³QºR·´¤§«e¡A ³]³Æ³£¥i¸g¥Ñ /dev/rtf[fifo] ¨Ó¦s¨ú¡C

  • rt_destroy(unsigned int fifo)¡G ¬Û¹ïÀ³ªº FIFO ·|³QºR·´¡A ¥B©Ò¦û¦³ªº°O¾ÐÅé·|­«·s¤À°t¡C

  • rt_fifo_put(fifo, char *buf, int count)¡G ¹Á¸Õ±q½w½Ä°Ï buf ¤¤¼g¤J count ­Ó¦ì¤¸²Õ¡C ¦pªG FIFO ªº½w½Ä°ÏªÅ¶¡¤£¨¬¡A ´N¶Ç¦^ -1¡C

  • rt_fifo_get(fifo, char *buf, count)¡G ¸ÕµÛ±q FIFO ¸ÌŪ¥X count ­Ó¦ì¤¸²Õ¡C ¦pªG¨S¦³¨¬°÷ªº¸ê®Æ¥i¥HŪ¨ú¡A ´N¶Ç¦^ -1¡C

¤U¤@­Ó¨Ò¤l¨Ó¬Ý¬Ý³o¨Ç¨ç¼Æªº¨Ï¥Î¤èªk¡C ³o¬O¤@­Ó RT-Linux¡]­µ®Ä¡^µo¦æ¨t²Î¤¤¡A °µ¹L¨Ç·L­×§ïªº¨Ò¤l¡G

example3.c
  #define MODULE
  #include <linux/module.h>
  #include <linux/rt_sched.h> 
	 
  #include <linux/rtf.h>
  #include <asm/io.h>

  RT_TASK task;  

  static int filter(int x){
    static int oldx;
    int ret;
    if (x & 0x80) {
      x = 382 - x;
    }
    ret = x > oldx;
    oldx = x;
    return ret;
  }

  void fun(int dummy) {
    char data;
    char temp;
    while (1) {
      if (rtf_get(0, &data, 1) >  0) {
        data = filter(data);
        temp = inb(0x61);            
        temp &= 0xfd;
        temp |= (data & 1) <<  1;
        outb(temp,0x61);
      }
      rt_task_wait();
    }
  }

  int init_module(void){
    rtf_create(0, 4000);
    
    /* enable counter 2 */
    outb_p(inb_p(0x61)|3, 0x61);
    
    /* to ensure  that the output of the counter is 1 */
    outb_p(0xb0, 0x43);
    outb_p(3, 0x42);
    outb_p(00, 0x42);
    
    rt_task_init(&task, fun,  0 , 3000, 1);   
    rt_task_make_periodic(&task, 
                   (RTIME)rt_get_time()+(RTIME)1000LL, 
                   (RTIME)(RT_TICKS_PER_SEC / 8192LL));

    return 0;
  } 

  void cleanup_module(void){
    rt_task_delete(&task);  
    rtf_destroy(0);
  }

¦p¦P²Ä¤G­Ó½d¨Ò©Ò¥Ü¡A §Ú­Ì»Ý­n rt_prio_sched ¼Ò²ÕªºªA°È¡A ¦ý¬O¡A ³o¤@¦¸¬°¤F¨Ï¥Î FIFO¡A §Ú­Ì¥²¶·¦P®É¸ü¤J rt_fifo_new ¼Ò²Õ¡C

ÀW²v 8192Hz ªº´`Àô§Y®É¨t²Î¥ô°È¤w¸g«Ø¦n¤F¡C ¦pªG³o¥ô°Èµo²{¦³¥ô¦óªº¸ê®Æ¡A °e¨ì PC µoÁn¾¹ªº¦ì§}ªú¡A ´N·|±q FIFO 0 ¸ÌŪ¨ú¦ì¤¸²Õªº¸ê®Æ¡C ¦pªG§Ú­Ì§â¤@­Ó ".au" ®æ¦¡ªº­µ®ÄÀɮ׫þ¨©µ¹ /dev/rtf0¡A ²{¦b´N¥i¥Hťť¬Ý­µ®ÄÀɪº­µ®Ä¦p¦ó¤F¡C ¦]¬° PC ªºµwÅé¡A ¶È¤¹³\¥H¤@¦ì¤¸¥h½Õ¸`«H¸¹¡A ©Ò¥H¤£¥²¥h¦b·N­µ®Äªº«~½è§C¦H¡C µo¦æ¨t²Îªº¥Ø¿ý testing/sound ¤¤¦³ linux.au ³o­ÓÀɮסA ¥i¥H¥Î¨Ó´ú¸Õ¡C

±µµÛ¬O½sĶµ{¦¡¡A µM«á°õ¦æ¡G

   # gcc -I /usr/src/linux/include/linux -O2 -Wall -D__KERNEL__ -D__RT__ -c example3.c
   # modprobe rt_fifo_new
   # modprobe rt_prio_sched
   # insmod example3.o
   # cat linux.au > /dev/rtf0

ª`·N¨ì cat ³o­Ó¤u¨ãµ{¦¡¬O«ç»ò¥Î¨Ó°µÂмgÀɮתº¡A ¥]§t¤F¯S®íÀɮסC ©R¥O cp ¦³¦P¼Ëªº®ÄªG¡C

­n¤ñ¸û§Y®É¨t²Îªº¯S¦â·|«ç¼Ë¼v·Q½Æ»s«~ªº«~½è¡A §Ú­Ì¥u¦n¥t¥~¦A¼g­Óµ{¦¡¡A ¥Î Linux ¥¿±`ªºµ{§Ç¨Ó³B²z¬Û¦Pªº¤u§@¡G

example4.c
  #include <unistd.h>
  #include <asm/io.h>
  #include <time.h>

  static int filter(int x){
    static int oldx;
    int ret;
    if (x & 0x80)
      x = 382 - x;
    ret = x > oldx;
    oldx = x;
    return ret;
  }
  espera(int x){
    int v;
    for (v=0; v<x; v++);
  }
  void fun() {
    char data;
    char temp;

    while (1) {
      if (read(0, &data, 1) >  0) {
        data = filter(data);
        temp = inb(0x61);
        temp &= 0xfd;
        temp |= (data & 1) << 1;
        outb(temp,0x61);
      }
      espera(3000);
    }
  }

  int main(void){
    unsigned char dummy,x;
    ioperm(0x42, 0x3,1); ioperm(0x61, 0x1,1);

    dummy= inb(0x61);espera(10);
    outb(dummy|3, 0x61);

    outb(0xb0, 0x43);espera(10);

    outb(3, 0x42);espera(10);
    outb(00, 0x42);

    fun();
  }

³o¤äµ{¦¡¥i¥H¹³¨ä¥L²³æªºµ{¦¡¨º¼Ë¨Ó½sĶ¡G

  # gcc -O2 example4.c -o  example4

And to execute it:

  # cat linux.au | example4

­n¸g¥Ñ Linux ªºµ{¦¡¨Ó¦s¨úµwÅ骺¦ì§}ªú¡A§Ú­Ì±o¥ý½Ð¨D§@·~¨t²Îªº­ã³\¡C ³o¬OÁקKµ{¦¡ª½±µ¦s¨úµwÅé¸ê·½¡A ³Ì°ò¥»¥B¥²­nªº«OÅ@±¹¬I¡C ¨Ò¦p¡A ©I¥s¨ç¼Æ ioperm() ·|§i¶D Linux¡A §Ú­Ì§Æ±æ¥h¦s¨ú¬Y¤@©w½d³òªº I/O ¦ì§}ªú¡C ¥u¦³·íµ{¦¡¬O¥H root ªº¨­¥÷¨Ó°õ¦æ®É¡A µ{¦¡¤~¦³¥i¯à±o¨ì³oºØÅv¤O¡C ¥t¤@­Ó­È±oª`·Nªº¬O¡A 8192Hz ªºÀW²v¦p¦ó½Õ¸`­µ®Ä¡A ¨Ï¨ä²£¥ÍÁn­µ¡C ÁöµM¦³­Ó¨t²Î©I¥s¨ç¼Æ nanodelay() ¥i¥Î¡A ¦ý³o­Ó¨ç¼Æ¶È¦³©T©wªº¦Ê¸U¤À¤§¤@¬í (milliseconds) ªº¸ÑªR«×¡F ¦]¦¹¡A §Ú­Ì¥²¶·¨Ï¥Î°j°é¨ÓµêÀÀµ¥«Ýªº®É¶¡¡A ¨Ï®ÉÄÁ·|¼È°±¤@¤U¤U¡C ³o­Óµ¥«Ý°j°é¥²¶·½Õ¾ã¨ì®t¤£¦h¥i¥H¦b 100MHz ªº Pentium ¤W°õ¦æ¡C

²{¦b¡A §Ú«ØijŪªÌ¤£§«´ú¸Õ¤@¤U example4 ©M ico¡C Án­µÅ¥°_¨Ó«ç»ò¼Ë¡S §ï´«¦¨§Y®É¨t²Îª©¥»ªº Linux ·Pı¦p¦ó¡S §Y®É¨t²Î¬O¤£¬O¦³»ù­È¥i¨¥©O¡S

µ²½×

²Ä¤G½g¤å³¹§âµJÂI©ñ¦b³]­p§Y®É¨t²Îµ{¦¡¡C ¤å³¹¤¤©Ò¦CÁ|ªºµ{¦¡½d¨Ò¡A ³£«D±`²³æ¥B¯Ê¥F¹ê»Ú¥Î³~¡A ±µ¤U¨Óªº¨t¦C¤å³¹¡A §Ú·|´£¥X§ó¦³¥ÎªºÀ³¥Î½d¨Ò¡C §Ú­Ì±N¥i¥H¥Î Linux ¨Ó±±¨î¹qµø¡A ¬Æ¦Ü©ó¥i¥H±q»·ºÝ¡A ¨Ó¨M©w§A©M§Aªº Linux ¤§¶¡³q°Tªº¤èªk (Linux box)!!!

°Ñ¦Ò¸ê®Æ¡G


¥»¤å¥Ñ Frank J.S. Chen ©Ò½Ķ

¥Dºô¯¸¥Ñ Miguel A Sepulveda ºûÅ@
© Ismael Ripoll 1998
LinuxFocus 1998