
                      Linux ׫дʽʹ I/O 
                                       
: Riku Saikkonen <Riku.Saikkonen@hut.fi>
: Da-Wei Chiang <dawei@sinica.edu.tw>

   v, 28 December 1997 : 22 Jul. - 1 Aug. 1998
     _________________________________________________________________
   
   ĵ˵ Intel x86 ܹʹģʽ (user-mode) ׫д
   ʽʹӲI/O ԼȴһСεʱ.
     _________________________________________________________________
   
1. 

2.  C ʹ I/O 

     * 2.1 ķ
     * 2.2 һķ: /dev/port
       
3. Ӳж (IRQs)  DMA ȡ

4. ߾ȷʱ

     * 4.1 ӳʱ
     * 4.2 ʱ
       
5. ʹʽ

6. һЩõ I/O 

     * 6.1 в (parallel port)
     * 6.2 Ϸ (ݡ)  (game port)
     * 6.3 в (serial port)
       
7. ʾ

8. ų

9. ʽ

10. л
     _________________________________________________________________
   
1. 

   ĵ˵ Intel x86 ܹʹģʽ (user-mode) ׫д
   ʽʹӲ I/O ԼȴһСεʱ. Դһƪǳ̵
   IO-Port mini-HOWTO 뱾ͬ.
   
    1995-1997 İȨ Riku Saikkonen . Ȩҳ
   [1]Linux HOWTO copyright.
   
   Աκָ̲Ǵݲ, ӭŸ
   (Riku.Saikkonen@hut.fi)...
   
   Ķǰһηеİ汾 (Mar 30 1997) µ:
   
     *  inb_p/outb_p Ͳλַ 0x80 ֮Ĺϵ˳.
     * ɾ˹ udelay() ʽ, Ϊ nanosleep() ʽ ṩ˱Ƚ
       ȷʹ÷.
     * ת Linuxdoc-SGML ʽ, Щı.
     * ԺܶطЩĲ.
       
2.  C ʹ I/O 

2.1 ķ

   ȡ I/O ĳʽ (Routine) ڵ /usr/include/asm/io.h  (
   ںԭʼʽ linux/include/asm-i386/io.h ). Щʽ
   Եо޼ (inline macros) ķʽдɵ, ʹʱֻҪ #include
   <asm/io.h> ķʽþ͹; Ҫκκʽ (libraries).
   
   ע: ʽ(Routine) ָͨϵͳ(System Call)뺯ʽ(Function)
   .
   
   Ϊ gcc (ٳ 2.7.2.3 ǰİ汾) Լ egcs (еİ汾) 
   , ڱκʹõЩʽԭʼʱ  ѻѡ (gcc -O1
   ϸ߲ε),  #include <asm/io.h> ǰʹ #define
   extern  extern ɿհ.
   
   Ϊ˳Ŀ, ʱʹ gcc -g -O (ڵ gcc 汾
   ), ѻ֮ʱܻó (debugger) Ϊе. 
   ״Ǹ, Խʹõ I/O ĳʽзһ
   ﲢֻڱõʱѻѡ.
   
   ȡκ I/O ֮ǰ, ĳʽȨ. ҪĿ
   ĳʽһʼĵط (Ҫκ I/O ȡ֮ǰ) 
   ioperm() ʽ (úʽ춵 unistd.h , ұ ).
   ʹ﷨ ioperm(from, num, turn_on),  from ǵһȡ
   I/O λַ, num ǽȡ I/O λַĿ. , ioperm(0x300,
   5, 1) ˼˵ȡ 0x300  0x304 (һλַ). һ
   һִֵָǷ ʽȡ I/O Ȩ (true
   (1)) ǳȥȡȨ (false (0)).  Զκкʽ ioperm() Ա
   ʹöĲλַ. ﷨ϸ ο ioperm(2) ʹ˵
   .
   
   ĳʽӵ root Ȩޡܺкʽ ioperm() ; 
   root ִиóʽ, ǵýóʽ setuid  root. йʽ
   ioperm()  I/O ĴȡȨõ root Ȩ. ĳʽ
   ֮Ტر Ҫ ioperm(..., 0) ʽõ I/O ĴȡȨ;
   Ϊĳʽ ִ֮Զ.
   
   кʽ setuid() ĿǰִгʽЧʹʶ (ID) 趨ɷ root
   ʹ߲Ӱǰ ioperm() ķʽȡõ I/O ȡȨ, Ǻ
   кʽ fork() ķʽȴӰ (Ȼг (parent process) дȡ
   Ȩ, г (child process) ȴ޷ȡôȡȨ).
   
   ʽ ioperm() ֻȡòλַ 0x000  0x3ff ĴȡȨ;  ϸλ
   ַĲ, ʹúʽ iopl() (úʽһοԴȡеĲλַ). Ȩ
   ޵ȼֵΪ 3 (, iopl(3)) Աĳʽܹȡ е I/O 
   (ҪС --- ȡĲλַĵɸֲԤڵ
   . ͬ, кʽ iopl() ӵ root Ȩ.﷨ϸο
   iopl(2) ʹ˵ļ.
   
   , ʵʵشȡ I/O ... Ҫĳλַһ byte (8 
   bits) , úкʽ inb(port) , úʽᴫȡõһ byte 
   . Ҫһ byte , úкʽ outb(value, port) (ס
   Ĵ). Ҫĳλַ x  x+1 ( byte һ word, ʹ
    ָ inw) һ word (16  bits) , úкʽ
   inw(x) ; Ҫһ word ϵλַ, úкʽ outw(value,
   x) . 㲻ȷʹǸָ (byte  word), Ҫ inb() 
   outb() ָ --- Ϊװöǲ byte СĲȡʽ
   Ƶ. עеĲȡָҪԼһ΢ʱִ.
   
   ʹõ inb_p(), outb_p(), inw_p(), Լ outw_p() Ⱦ޼ָ, 
   Բλַȡ̵ֻ֮ܶ(Լһ΢)ӳʱͿ; Ҳ
   ӳʱɴԼ΢뷽ʹ #include <asm/io.h> ֮ǰʹ
   #define REALLY_SLOW_IO. Щ޼ָͨ (ʹõ #define
   SLOW_IO_BY_JUMPING, ܽϲ׼ȷ) ϵλַ 0x80
   ԱﵽӳʱĿ, Ժʽ ioperm() ȡòλַ 0x80 ʹ
   Ȩ (ϵλַ 0x80 ӦûϵͳӰ). 
    ͨõӳʱķ, ȥ.
   
   ioperm(2), iopl(2) Ⱥʽ, ľ޼ָʹ˵¼ 
    Linux ʹ˵ļ.
   
2.2 һķ: /dev/port

   һȡ I/O ķԺʽ open()  /dev/port (һԪװ
   ,ҪװñΪ 1, ҪװñΪ 4) Աִж/дĶ (ע
   ׼ (stdio) ʽ f*() ڲĻ (buffering), Ҫʹ).
   ʹ lseek() ʽԱڸԪװõҵĳ byte ϵȷλ
   (λ 0 = λַ 0x00, λ 1 = λַ 0x01, Դ), Ȼ
   ʹ read()  write() ʽĳλַдһ byte  word 
   ϵĶ.
   
   ķĳʽʹ read/write ʽȡ /dev/port Ԫ
   װõ. ִٶȻǰһ㷽, ǲҪ
    ѻҲҪʹúʽ ioperm() .  root ʹ߻
   Ⱥȡ /dev/port Ԫװð, ʱͲӵ root Ȩ -- Ƕ
   ϵͳȫ Ǹǳ, Ϊ˺ϵͳ, 
   ȡ root Ȩ,  /dev/port ԪװõֱӴȡӲ, ·, 
   豸.
   
3. Ӳж (IRQs)  DMA ȡ

   ĳʽʹģʽ (user-mode) ִвֱʹӲж
   (IRQs)  DMA. ׫дһʽ; صϸοҳ [2]The
   Linux Kernel Hacker's Guide Լúĳʽԭʼ.
   
   Ҳ˵, ʹģʽ (user-mode) дĳʽ޷ӲжϵĲ
   .
   
4. ߾ȷʱ

4.1 ӳʱ

   , һ˵֤ʹģʽ (user-mode) ִег (process) 
   ȷؿʱΪ Linux Ǹ๤ҵ. ִег
   (process) ʱΪԭͣԼ 10 뵽 (ϵͳɷǳ
   ʱ). Ȼ, 춴ʹ I/O Ӧö, ӳʱʵ㲻
   ʲ. Ҫӳʱ, ʹúʽ nice ִег (process
   ) 趨ɸȨ(ο nice(2) ʹ˵ļ) ʹüʱų̷
   (real-time scheduling) (뿴).
   
   ñһʹģʽ (user-mode) ִег (process) Ҫ
   ȷʱ, һЩʹģʽ (user-mode)  `ʱ' 
   ̵֧Ԯ. Linux 2.x 汾ĺ巽ʽļʱų֧Ԯ; ϸ˵
   ο sched_setscheduler(2) ʹ˵ļ. һĺ֧ԮӲļʱ
   ų; ϸѶοҳ [3]http://luz.cs.nmt.edu/~rtlinux/
   
  Ϣ (Sleeping) : sleep()  usleep()
  
   , ǿʼϼ򵥵ʱʽ. Ҫӳʱ, ѵķ
    ʹúʽ sleep() . Ҫӳʮʱ (10 ms ƺ
    ӳʱ), ʽ usleep() Ӧÿʹ. Щʽó CPU ʹȨ
   Ҫִег (processes) (``ԼϢȥ''), û˷ѵ
   CPU ʱ. ϸο sleep(3)  usleep(3) ˵ļ.
   
   ó CPU ʹȨʹʱӳ˴Լ 50  (ȡ춴
   ٶ, Լϵͳĸ), ˷ѵ CPU ̫ʱ, Ϊ Linux ų
   (scheduler) ( x86 ܹ) ڽȨг (process) ֮ǰ
   ͨҪ 10-30 ʱ. , ʱӳ, ʹúʽ
   usleep(3) õӳٽͨڲֵָ, Լ 10
   ms.
   
  nanosleep()
  
    Linux 2.0.x һϵеĺķа汾, һµϵͳ (system
   call), nanosleep() (ο nanosleep(2) ˵ļ), ܹ Ϣ
   ӳһ̵ʱ (΢).
   
   ӳٵʱ <= 2 ms, (Ψ)ִег (process) 趨
   ʱ ų (ʹúʽ tt/sched_setscheduler()/), кʽ
   nanosleep() ʱ ʹһæµȦӳʱ; ǻʽ usleep() һ
   ó CPU ʹȨϢȥ.
   
   æµȦʹúʽ udelay() (һʽõĺڲĺʽ) 
   , ʹ BogoMips ֵ (BogoMips ׼ȷæµȦٶ) 
   Ȧӳٵʱ䳤. ζϸο
   /usr/include/asm/delay.h).
   
  ʹ I/O ӳʱ
  
   һӳ΢ķʹ I/O . ǴӲλַ 0x80 κ
   byte  (οǰ) ȴʱӦüֻҪ 1 ΢ҪĴ
   ͱٶ. Ҫӳ΢ʱԽ. κα
   ׼Ļϵ λַӦòв (Щĵ
   ʽҲʹ). {in|out}[bw]_p() Ⱥʽʹʱ
   ӳٵ (ο asm/io.h).
   
   ʵ, һʹõλַΧΪ 0-0x3ff  I/O ָֻҪ 1 ΢ʱ
   , Ҫ, , ֱʹòв, ֻҪϼ inb() ʽ
    λַΧ byte ϼ.
   
  ʹӳʱ
  
   ִ֪гʽڻĴͱʱٶ, ִĳЩ
   ָԱý϶̵ӳʱ (Ǽס, ִег (process) ʱ
   ᱻͣ, ʱӳٵʱʵʳ). ıʾ, ڲ
   ٶȾҪʹõʱ; , һ 50 MHz Ĵ (486DX-50 
   486DX2-50), һʱҪ 1/50000000  (=200 ).
   
ָ          i386 ʱ       i486 ʱ
nop                   3                   1
xchg %ax,%ax          3                   3
or %ax,%ax            2                   1
mov %ax,%ax           2                   1
add %ax,0             2                   1

   (Բ, Ҳ֪ Pentiums ,  i486 ӽ. ޷ i386 
   ҵֻһʱڵָ. ܹʹûһʱڵ
   ָ, ҪȻʹù߼ʽҲǿʱ.)
   
   ıָ nop  xchg Ӧòв. ָܻ ı
   ݴ, ûϵΪ gcc ᴦ. ָ nop Ǹõѡ.
   
   ҪĳʽʹõЩָ, ʹ asm("instruction"). ָ﷨
   ͬ÷; Ҫڵһ asm() ʹöָ, 
   ʹ÷ֺŽǸ. , asm("nop ; nop ; nop ; nop") ִĸ nop
   ָ,  i486  Pentium лӳĸʱ ( i386 ӳ
   12 ʱ).
   
   gcc Ὣ asm() ɵԳʽ, Բккʽĸ.
   
    Intel x86 ܹвбһʱڻ̵ʱӳ.
   
   Pentiums ʹúʽ rdtsc
  
    Pentiums , ʹ C ԳʽȡԴϴ
   ¿ ھ˶ٸʱ:
       ______________________________________________________________
     
   extern __inline__ unsigned long long int rdtsc()
   {
     unsigned long long int x;
     __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
     return x;
   }
       ______________________________________________________________
     
   ѯʲοֵԱӳҪʱ.
   
4.2 ʱ

   Ҫʱ侫ȷһ, ʹúʽ time() 򵥵ķ. Ҫʱ
   ȷ, ʽ gettimeofday() ԼԾȷ΢ (ǰܵ CPU ų
   Ӱ).  Pentiums , ʹĳʽƬϾͿԾȷһʱ
   .
   
   Ҫִег (process) һʱ䵽ܹ֪֮ͨ (get a
   signal), ʹúʽ setitimer()  alarm() . ϸοʽʹ˵
   ļ.
   
5. ʹʽ

   ˵ C ʽ. ӦÿֱӦ C++  Objective C ֮
   . Բ, Ȼ C ккʽ ioperm() 
   iopl() , ֮Ϳֱʹ I/O дָ.
   
   ʽ, ڸóʽв뵥Ի C ֮
   ʽʹ˵ϵͳ, 򵹲׫дһںдȡ I/O 
   ʱ躯ʽ֮򵥵 C ԭʼʽȽ, ֮ĳ
   ʽ. ҪȻʹǰ˵ /dev/port Ԫװõ.
   
6. һЩõ I/O 

   ṩһЩ I/O ĳʽ׫дѶЩǿֱõһĿ
   TTL ( CMOS) ߼λ׼ I/O .
   
   ҪԭʼĿʹЩõI/O  (, һ
   ӡݻ), Ӧûʹֳɵװʽ (ͨں
   ) 籾˵ȥ׫д I/O ʽ. ҪṩЩҪ
   LCD ʾ, , ҵӲƷ ӵ PC ׼ I/O .
   
   Ҫƴгװɨ (Ѿгһ
   ), ȥҿǷֳɵ Linux װʽ. ҳ [4]Hardware-HOWTO 
   õĲο.
   
   Ҫ֪йӵװõ(Լһĵѧԭ)
   Ѷҳ [5]http://www.hut.fi/Misc/Electronics/ ǸõԴ.
   
6.1 в (parallel port)

   вĻλַ (³֮Ϊ ``BASE'') ֮ /dev/lp0  0x3bc , ֮
   /dev/lp1  0x378 , ֮ /dev/lp2  0x278 . ֻҪһЩ
   һӡĶ, Բοҳ [6]Printing-HOWTO.
   
   漴ı׼ (output-only) ģʽ, Ĳв `
   ' ˫ (bidirectional) ģʽ. 춽µ ECP/EPP ģʽ (Լһ
   IEEE 1284 ׼) ڵ, Բοҳ [7]http://www.fapo.com/ 
    [8]http://www.senet.com.au/~cpeacock/parallel.htm. Ϊʹģʽ
   (user-mode) еĳʽ޷ʹ IRQs  DMA, Ҫʹ ECP/EPP ģʽ
   ׫дһĵװʽ; Ӧдװʽ, 
   Ҳ֪.
   
   λַ BASE+0 (ϲ) ϲźλ׼ (D0  D7 ֱ
   bits 0  7, λ׼״̬: 0 = λ׼ (0 V), 1 = λ׼ (5 V)). һд
   ϵòĶὫźλ׼˩ס (latches) ڲĽλ (pins) . һ
   ò϶ĶὫһԱ׼ (output-only) ģʽ
   дģʽ˩סźλ׼, ģʽ һ װý
   λϵźλ׼.
   
   λַ BASE+1 (״̬) Ǹ (read-only) Ĳ, Ὣźλ
   ׼:
     * Bits 0  1 .
     * Bit 2 IRQ ״̬ (Ǹλ (pin) , Ҳ֪Ĺԭ)
     * Bit 3 ERROR (1=λ׼)
     * Bit 4 SLCT (1=λ׼)
     * Bit 5 PE (1=λ׼)
     * Bit 6 ACK (1=λ׼)
     * Bit 7 -BUSY (0=λ׼)
       
   (Ҳȷߵλ׼ĵѹ״̬.)
   
   λַ BASE+2 (Ʋ) Ǹд (write-only) Ĳ (һò϶
   ĶὫһдźλ׼), ״̬ź:
     * Bit 0 -STROBE (0=λ׼)
     * Bit 1 AUTO_FD_XT (1=λ׼)
     * Bit 2 -INIT (0=λ׼)
     * Bit 3 SLCT_IN (1=λ׼)
     * Bit 4 趨Ϊ 1 ʱв IRQ ź ( ACK λλ׼
       ɵͱߵ˲)
     * Bit 5 ģʽʱ뷽 (0 = д, 1 = ), Ǹд
       (write-only) Ĳ (һò϶ĶԴ bit һôҲû
       ).
     * Bits 6 and 7 .
       
   (ͬ, Ҳȷߵλ׼ĵѹ״̬.)
   
   Ľλ (Pinout) ʽ (òһ 25 ֻ D  (D-shell) 
   ĸͷ) (i=, o=):
   
1io -STROBE, 2io D0, 3io D1, 4io D2, 5io D3, 6io D4, 7io D5, 8io D6,
9io D7, 10i ACK, 11i -BUSY, 12i PE, 13i SLCT, 14o AUTO_FD_XT,
15i ERROR, 16o -INIT, 17o SLCT_IN, 18-25 Ground

   IBM Ĺļ˵λ 1, 14, 16,  17 (źŵ) õ羧Ŀ
    (open collector) ʽʹ 4.7 Ǫŷķ (kiloohm) 
    5 V ĵѹ ( 20 mA,  0.55 mA, λ׼ѹ
    5.0 V ȥĵѹ). ʣĽλ 24 mA, 
   15 mA, λ׼ѹС 2.4 V. λ׼ѹ߶ 0.5 V.
   Щ IBM Ĳвƫ׼. οҳ
   [9]http://www.hut.fi/Misc/Electronics/circuits/lptpower.html.
   
   , һ: Ľӵص. ڵԻǿ״ȥ
    Ūüв. ܻûǲҪв
   ϵȽϺ. (ͨһƬ˵ı׼ `multi-I/O' װ
    в; ֻҪҪĲͣ, ȻὫƬϲвĲλַ趨
   λַ. 㲻Ⲣв IRQ 趨, Ϊͨᱻõ.)
   
6.2 Ϸ (ݡ)  (game port)

   ϷĲλַΧΪ 0x200-0x207. ҪһĲݡ, һĲ
   Ĳݡʽ, ɲοַ
   [10]ftp://sunsite.unc.edu/pub/Linux/kernel/patches/,  joystick-*.
   
   Ľλ (Pinout) ʽ (òһ 15 ֻ D  (D-shell) 
   ĸͷ):
     * 1,8,9,15: +5 V (Դ)
     * 4,5,12: ӵ
     * 2,7,10,14: ֱ BA1, BA2, BB1,  BB2 λ
     * 3,6,11,13: ֱ AX, AY, BX,  BY ``''
       
   +5 V ĽλƺͨᱻֱӵĵԴ, Ӧܹṩ
   ĵ, ⻹Ҫʹ, Դ, ԼϷ.
   
   λ춲ݡİťӶݡĸť (ݡ A 
   ݡ B, жť) ϷҲλĸλ. Ӧһ
    TTL ѹλ׼, ֱӴ״̬ (ο˵) ǵλ׼
   ״̬. һʵʵĲݡڰťѹʱᴫصλ׼ (0 V) ״̬Ǹλ
   ׼ (5V  1 Kohm ĵӵԴλ) ״̬.
   
   νʵ⵽迹ֵ. Ϸĸг
   (one-shot multivibrator) (һ 558 Ƭ) ӵĸλ. ÿ
   λг֮һ 2.2 Kohm ĵ, Ҷг
   ֮һ 0.01 uF ʱ (timing capacitor). һ
   ʵʵĲݡÿ (X  Y) ϻһɱ,  +5 V ÿ
   Եλ֮ (λ AX  AY Ǹݡ A õ, λ BX 
   BY Ǹݡ Bõ).
   
   ʱ, г趨Ϊλ׼ (5 V) ҵȵʱϵĵ
   ѹﵽ 3.3 V ֮ὫԵ趨Ϊλ׼. ˲ݡжг
   λ׼ʱ ɱĵֵ (Ҳ, ݡλ
   ), ʾ:
   
     R = (t - 24.2) / 0.011,
     
    R ǿɱ迹ֵ (ohms)  t Ǹλ׼ʱڵĳ ().
   
   Ҫλֵ, г (Բдķʽ;
   뿴), Ȼѯĸź״̬(ԳĲʽ)һֱź״̬
   ɸλ׼ɵλ׼, λ׼ʱڵĳ. ѯĶ
   ൱ CPU ʱ, һǼʱĶ๤ (һʹģʽ
   (user-mode) ) Linux, õĽǷǳ׼ȷΪ޷Թ̶ʱѯ
   źŵ״̬ (ʹúĲεʽѯʱƵ
   ϵĲ, ˷Ѹ CPU ʱ). ֪źŵ״̬Ứ
   һβ̵ʱ (ʮ) Ϊλ׼, ڲѯ֮ǰкʽ
   usleep()  CPU ʱøҪִег (processes).
   
   ϷΨһҪȡĲλַ 0x201 (ĲλַǶһ
   û). κζλַд붯 (дʲ) г
   . λַȡźŵ״̬:
     * Bit 0: AX ( (1=λ׼) г״̬)
     * Bit 1: AY ( (1=λ׼) г״̬)
     * Bit 2: BX ( (1=λ׼) г״̬)
     * Bit 3: BY ( (1=λ׼) г״̬)
     * Bit 4: BA1 (λ, 1=λ׼)
     * Bit 5: BA2 (λ, 1=λ׼)
     * Bit 6: BB1 (λ, 1=λ׼)
     * Bit 7: BB2 (λ, 1=λ׼)
       
6.3 в (serial port)

   ˵װ֧ԮһЩ RS-232 Ķ, ӦÿԸ
   ʹôв. Linux ṩĴвʽӦܹӦκεط (Ӧ
   Ҫֱ׫двʽ, Ǻĵʽ); ൱ͨ, 
   ʹ÷Ǳ׼ bps ԼȵӦò. ο termios(3) ˵
   ļ, вʽԭʼʽ (linux/drivers/char/serial.c), Լҳ
   [11]http://www.easysw.com/~mike/serial/index.html и Unix ҵ
   ϵͳ׫двʽ.
   
7. ʾ

   Ҫкõ I/O Ʒֵ, ڲвװ ADC / DAC Ƭ
   (ʾ: Դ, ʹϷϵĻδõĴŵԴͷ ֮
   , װùĵòв䵱Դ, Ȼʹⲿ
   Դ),  AD/DA Ƭ (󲿷ֽϾ/ϵٵĲƷ I/O 
   ).  Linux Чʽ֧ԮıЧ (ٶȻ൱Ŀ) 
   1  2 ȷ, (ܻ) ޷źͨԾ͹.
   
   ʹþȷװ, Ľӵؿźŵ. 
   ľ, ᳢ܻԹ (װ֮ е 
   ) Ӹ. ӵȡùĵԴ (ڲδõźŽλ
   ṩ㹻ĵԴ) ﵽѵĸЧ.
   
   Ѱ Linux ʹõӡˢ·, һΪ
   Pcb ѵ X11 ӦóʽӦܹʤ, ֻҪ㲻ҪһЩ̫ӵ. 
   Linux а汾 (distributions) ںʽ, ͬʱҲַ
   [12]ftp://sunsite.unc.edu/pub/Linux/apps/circuits/ (Ϊ pcb-*).
   
8. ų

   Q1.
          Ҵȡ I/O ʱ segmentation faults 
          
   A1.
          ĳʽû root Ȩ, ΪĳЩɵºʽ ioperm() 
          ʧ. 麯ʽ ioperm() Ĵֵ. ͬʱ, ȡĲҲ
           ʽ ioperm() õĲλַ (ο Q3). ʹõӳ
          ʱľ޼ָ (inb_p(), outb_p(), ȵ), ǵҲҪкʽ
          ioperm() Աȡλַ 0x80.
          
   Q2.
          ޷ҵ in*(), out*() Ⱥʽںδ, ͬʱ gcc ҲԹο
          δķ (undefined references).
          
   A2.
          ڱʽʱûдѻѡ (-O),  gcc ܽ
          asm/io.h еľ޼ָ. ûʹ #include
          <asm/io.h>.
          
   Q3.
          out*() ûж, Ƕֵֹ.
          
   A3.
          õĴ; Ӧ outb(value, port) , 
          MS-DOS ϳõ outportb(port, value)
          
   Q4.
          Ҫһ׼ RS-232 װ/Ӳвӡ/ݡ...
          
   A4.
          ֹͣ¶ʹеʽ (Ǵ Linux ĺ
           X ŷлĵط) Ŀ. Щʽͨ൱
          ͨ, Ծе㲻׼װ, ͨ. Щ
          ׼ I/O Ѷοǰ˵ļָ.
          
9. ʽ

   һȡ I/O ļ򵥵ĳʽ:
       ______________________________________________________________
     
/*
 * example.c: һȡ I/O ķǳ򵥵ġ
 *
 * ʽ벢ûʲô, ֻ˲д, ͣ,
 * ԼĶ. ʱʹ `gcc -O2 -o example example.c',
 *  root ִ `./example'.
 */

#include <stdio.h>
#include <unistd.h>
#include <asm/io.h>

#define BASEPORT 0x378 /* lp1 */

int main()
{
  /* ȡòλַĴȡȨ */
  if (ioperm(BASEPORT, 3, 1)) {perror("ioperm"); exit(1);}

  /* 趨ź (D0-7) ȫΪ (0) */
  outb(0, BASEPORT);

  /* Ϣһ (100 ms) */
  usleep(100000);

  /* ״̬ (BASE+1) ϲʾ */
  printf("status: %d\n", inb(BASEPORT + 1));

  /* ǲҪЩλַ */
  if (ioperm(BASEPORT, 3, 0)) {perror("ioperm"); exit(1);}

  exit(0);
}

/*  example.c */
       ______________________________________________________________
     
10. л

   Эҵʵ̫޷һһг, Ҫλ˵л. 
   Эҵ˲ûһһظϱǸ֮, ٴллǵЭ.

References

   1. http://sunsite.unc.edu/pub/Linux/docs/HOWTO/COPYRIGHT
   2. http://www.redhat.com:8080/HyperNews/get/khg.html
   3. http://luz.cs.nmt.edu/~rtlinux/
   4. http://sunsite.unc.edu/pub/Linux/docs/HOWTO/Hardware-HOWTO
   5. http://www.hut.fi/Misc/Electronics/
   6. http://sunsite.unc.edu/pub/Linux/docs/HOWTO/Printing-HOWTO
   7. http://www.fapo.com/
   8. http://www.senet.com.au/~cpeacock/parallel.htm
   9. http://www.hut.fi/Misc/Electronics/circuits/lptpower.html
  10. ftp://sunsite.unc.edu/pub/Linux/kernel/patches/
  11. http://www.easysw.com/~mike/serial/index.html
  12. ftp://sunsite.unc.edu/pub/Linux/apps/circuits/
