
                     pb Linux Ug{Өϥ I/O 
                                       
@: Riku Saikkonen <Riku.Saikkonen@hut.fi>
Ķ: Da-Wei Chiang <dawei@sinica.edu.tw>

   v, 28 December 1997 ½Ķ: 22 Jul. - 1 Aug. 1998
     _________________________________________________________________
   
   媺eF Intel x86 [cUpbϥΪ̼Ҧ (user-mode) g{
   ӨϥεwI/O Hεݤ@pqɶP.
     _________________________________________________________________
   
1. 

2. pb C yUϥ I/O 

     * 2.1 Wk
     * 2.2 t@ӴNk: /dev/port
       
3. w餤_ (IRQs) P DMA s

4. Tɧ

     * 4.1 ɶ
     * 4.2 ɶq
       
5. ϥΨL{y

6. @ǦΪ I/O 

     * 6.1 æC (parallel port)
     * 6.2 C (a)  (game port)
     * 6.3 C (serial port)
       
7. 

8. Dư

9. {Xd

10. P
     _________________________________________________________________
   
1. 

   媺eF Intel x86 [cUpbϥΪ̼Ҧ (user-mode) g{
   Өϥεw I/O Hεݤ@pqɶP. e۩@gD`u峹
   IO-Port mini-HOWTO @̻PP.
   
    1995-1997 vݩ Riku Saikkonen Ҧ. vnԨ
   [1]Linux HOWTO copyright.
   
   pGz糧妳Ф׬O~ץάOeɭz, wHH
   (Riku.Saikkonen@hut.fi)...
   
   e@o檺 (Mar 30 1997) @FpUץ:
   
     *  inb_p/outb_p M} 0x80 YXFM.
     * RF udelay() 禡, ] nanosleep() 禡 ѤF
       TϥΤk.
     * Neഫ Linuxdoc-SGML 榡, åBs@Fǳ\s.
     * ܦha@Fǳ\ɭzPץ.
       
2. pb C yUϥ I/O 

2.1 Wk

   ΨӦs I/O 𪺱` (Routine) bɮ /usr/include/asm/io.h  (
   b֤߭lX{ linux/include/asm-i386/io.h ɮ׸). oǱ`O
   H楨 (inline macros) 覡g, ҥHϥήɥunH #include
   <asm/io.h> 覡ޥδNF; ݭn[禡] (libraries).
   
   Ķ`: `(Routine) q`OtΩIs(System Call)P禡(Function)`
   .
   
   ] gcc (ܤ֥X{b 2.7.2.3 MHe) H egcs (Ҧ) 
   , AbsĶϥΨoǱ`lX  }̨Τƿﶵ (gcc -O1
   θh), Ϊ̬Ob #include <asm/io.h> oӰʧ@eϥ #define
   extern N extern wqť.
   
   Fت, AsĶɥiHϥ gcc -g -O (ܤֲ{b gcc Oo
   ), ǪΤƤᦳɥi| (debugger) 欰ܪI_. p
   GoӪpAӨOӧxZ, AiHNҦϥΨ I/O 𪺱`b@
   ɮ׸̨åubsĶɮ׮ץ}̨Τƿﶵ.
   
   bAs I/O 𤧫e, AA{pv. nFoӥت
   AiHbA{@}la (Onb I/O sʧ@e) Is
   ioperm() oӨ禡 (Ө禡Qŧiɮ unistd.h , åBQwqb ֤ߤ).
   ϥλykO ioperm(from, num, turn_on), 䤤 from OĤ@Ӥ\s
   I/O }, num O۳ss I/O }ƥ. Ҧp, ioperm(0x300,
   5, 1) NNO\s 0x300  0x304 (@@Ӱ}). ӳ̫@
   ӰѼƬO@ӥLNƭȥΨӫwO_ {s I/O v (true
   (1)) άOhsv (false (0)). A iHhIs禡 ioperm() HK
   ϥΦhӤs򪺰}. ܩykӸ` Ѧ ioperm(2) ϥλ
   .
   
   A{֦ root vׯIs禡 ioperm() ; ҥHApGOH
   root ӵ{, NOoNӵ{ setuid  root. AIsL禡
   ioperm() } I/O 𪺦svAKiH root v. bA{
   äSO nDAH ioperm(..., 0) oӤ覡 I/O 𪺦sv;
   ]A{ 槹oӰʧ@|۰ʧ.
   
   Is禡 setuid() Nثe{ĨϥΪѧOX (ID) ]wD root
   ϥΪ̨ävTeH ioperm() 覡Ҩo I/O sv, OI
   s禡 fork() 覡o|ҼvT (M{ (parent process) Os
   v, Ol{ (child process) oLkosv).
   
   禡 ioperm() uAo} 0x000  0x3ff sv; ܩ 
   }, AoϥΨ禡 iopl() (Ө禡A@iHsҦ}). Nv
   ŰѼƭȳ] 3 (Ҧp, iopl(3)) HKA{s Ҧ I/O 
   (]np --- pGs~}NAqyUؤiwl
   `. P˦a, Is禡 iopl() Ao֦ root v.ܩykӸ`аѦ
   iopl(2) ϥλ.
   
   , ڭ̨ӹڦas I/O ... nqYӰ}J@ byte (8 
   bits) , AoIs禡 inb(port) , Ө禡|Ǧ^Ҩo@ byte 
   . nX@ byte , AoIs禡 outb(value, port) (аO
   ƪ). nqYGӰ} x M x+1 (G byte զ@ word, Gϥβ
   Xy O inw) J@ word (16  bits) , AoIs禡
   inw(x) ; nX@ word ƨGӰ}, AoIs禡 outw(value,
   x) . pGATwϥΨӰO (byte  word), Ajn inb() P
   outb() oGӰO --- ]jhƪ˸mOĥ byte jps覡
   ӳ]p. `NҦsOܤֻݭnj@LɶӰ.
   
   pGAϥΪO inb_p(), outb_p(), inw_p(), H outw_p() O, b
   A@}sʧ@uݫܵu(j@L)ɶNiH; A]
   iHɶܦj|LkObϥ #include <asm/io.h> eϥ
   #define REALLY_SLOW_IO. oǥOq` (DAϥΪO #define
   SLOW_IO_BY_JUMPING, oӤkiǽT) |QοXƨ} 0x80
   HKF쩵ɶت, ҥHAoH禡 ioperm() o} 0x80 
   v (Xƨ} 0x80 ӷ|tΪLLyvT). 
    LqΪɶk, ~ŪUh.
   
   ioperm(2), iopl(2) 禡, MWҭzΪOϥλ|b 
   X Linux ϥλ󶰤.
   
2.2 t@ӴNk: /dev/port

   t@Ӧs I/O 𪺤kOH禡 open() }ɮ /dev/port (@Ӧr
   m,Dn˸ms 1, n˸ms 4) HKŪB/μgʧ@ (`N
   ǿXJ (stdio) 禡 f*() w (buffering), ҥHnקKϥ).
   ۨϥ lseek() 禡HKbӦr˸mɮפY byte ƪTm
   (ɮצm 0 = } 0x00, ɮצm 1 = } 0x01, H), MA
   iHϥ read()  write() 禡YӰ}Ūμg@ byte  word 
   ƪʧ@.
   
   oӴNkNObA{̨ϥ read/write 禡Ӧs /dev/port r
   ˸mɮ. oӤktשγ\e@kٺC, Oݭns
   Ķ ̨Τƥ\]ݭnϥΨ禡 ioperm() . pGA\D root ϥΪ̩
   sզs /dev/port r]˸m, ާ@ɴNݾ֦ root v -- O
   tΦwӨ OӫD`V|Ʊ, ]Liˮ`At, γ\|H]
   Ө root v, Q /dev/port r˸mɮתsw, d, 
   ].
   
3. w餤_ (IRQs) P DMA s

   A{pGbϥΪ̼Ҧ (user-mode) U椣iHϥεw餤_
   (IRQs)  DMA. Aݼg@Ӯ֤Xʵ{; Ӹ`аѦҺ [2]The
   Linux Kernel Hacker's Guide Hή֤ߵ{lXӷd.
   
   ]NO, AbϥΪ̼Ҧ (user-mode) Ҽg{Lkw餤_
   .
   
4. Tɧ

4.1 ɶ

   , ڷ|OҧAbϥΪ̼Ҧ (user-mode) 檺{ (process) 
   TaɧǦ] Linux OӦhu@~. Ab椤{
   (process) Hɷ|]Uح]QȰj 10 @Ƭ (btέtD`
   ɭ). M, jhƨϥ I/O ΦӨ, oөɶڤW⤣
   F. nYuɶ, AoϥΨ禡 nice NAb椤{ (process
   ) ]wuv(аѦ nice(2) ϥλ) ΨϥΧYɱƵ{k
   (real-time scheduling) (ЬݤU).
   
   pGAQob@ϥΪ̼Ҧ (user-mode) 檺{ (process) ٭n
   Tɧ, @ǤkiHAbϥΪ̼Ҧ (user-mode)  `Y' 
   {䴩. Linux 2.x ֤ߤn覡YɱƵ{䴩; ԲӪ
   Ѧ sched_setscheduler(2) ϥλ. @ӯS֤ߤ䴩w骺Y
   Ƶ{; ԲӪTаѦҺ [3]http://luz.cs.nmt.edu/~rtlinux/
   
  𮧤 (Sleeping) : sleep() P usleep()
  
   {b, ڭ̶}l²檺ɧǨ禡Is. QnƬɶ, ̨Ϊkj
    OϥΨ禡 sleep() . QnܤּƤQ@ɶ (10 ms GwO̵u
    ɶF), 禡 usleep() ӥiHϥ. oǨ禡OX CPU ϥv
   LQn檺{ (processes) (``ۤv𮧥hF''), ҥHSO
   CPU ɶ. Ӹ`аѦ sleep(3) P usleep(3) .
   
   pGX CPU ϥv]ӨϱoɶFj 50 @ (oMBzP
   t, HΨtΪt), NO CPU Ӧhɶ, ] Linux Ƶ{
   (scheduler) (N x86 [cӨ) bNvoٵA{ (process) e
   q`ܤ֭nO 10-30 @ɶ. ], uɶ, ϥΨ禡
   usleep(3) ұo쪺𵲪Gq`|jAbѼƩҫw, jܤ֦ 10
   ms.
   
  nanosleep()
  
   b Linux 2.0.x @tC֤ߵo檩, @ӷstΩIs (system
   call), nanosleep() (аѦ nanosleep(2) ), LA 𮧩
   @ӵuɶ (ƷLΧh).
   
   pG𪺮ɶ <= 2 ms, Y(B߭Y)A椤{ (process) ]wFn骺
   Y Ƶ{ (NOϥΨ禡 tt/sched_setscheduler()/), Is禡
   nanosleep()  OϥΤ@ӦLjөɶ; NO|禡 usleep() @
   X CPU ϥv𮧥hF.
   
   oӦLjϥΨ禡 udelay() (@Xʵ{`|Ψ쪺֤ߤ禡) 
   F, åBϥ BogoMips  (BogoMips iHǽTqoLj骺t) 
   pj驵𪺮ɶ. pʧ@Ӹ`аѦ
   /usr/include/asm/delay.h).
   
  ϥ I/O өɶ
  
   t@өƷLkOϥ I/O . NOq} 0x80 JοX
   byte  (аѦҫe) ݪɶӴXGun 1 LonݧABz
   OPt. pGnƷLɶAiHNoӰʧ@hX. b
   ǪWXƨ }Ӥ|}G׹ (ӥBǮ֤ߪ]
   Xʵ{]bϥΥL). {in|out}[bw]_p() 禡NOϥγoӤkӲͮ
    (аѦɮ asm/io.h).
   
   ڤW, @ӨϥΨ}d 0-0x3ff  I/O OXGun 1 L
   , ҥHpGAnp, Ҧp, ϥΨæC, un[WX inb() 禡q
    }dŪJ byte ƧYi.
   
  ϥβզXyөɶ
  
   pGAD{ҦbBzOPt, AiHYǲզXy
   OHKouɶ (OO, Ab椤{ (process) H
   |QȰ, ҥHɩ𪺮ɶ|ڪ). pUҥ, Bz
   tרMwFҭnϥΪP; p, @ 50 MHz Bz (486DX-50 
   486DX2-50), @ӮPnO 1/50000000  (=200 `).
   
O          i386 P       i486 P
nop                   3                   1
xchg %ax,%ax          3                   3
or %ax,%ax            2                   1
mov %ax,%ax           2                   1
add %ax,0             2                   1

   (藍_, ڤD Pentiums , γ\P i486 a. ڵLkb i386 
   ƤWuO@ӮPO. pGNШϥΪO@ӮP
   O, nMNϥκ޽u޳NsBz]OiHYuɶ.)
   
   W椤O nop P xchg Ӥ|}G. O̫i| 
   XȦse, OoSY] gcc |Bz. O nop OӦn.
   
   QnbA{ϥΨoǫO, Aoϥ asm("instruction"). Oyk
   NpPW檺Ϊk; pGAQnb@ asm() ԭzϥΦhӫO, iH
   ϥΤNL̹j}. Ҧp, asm("nop ; nop ; nop ; nop") || nop
   O, b i486  Pentium Bz||ӮP (άO i386 |
   12 ӮP).
   
   gcc |N asm() ½ĶզXy{X, ҥH|Is禡t.
   
   b Intel x86 [ci঳@ӮPٵuɶ.
   
  b Pentiums BzWϥΨ禡 rdtsc
  
    Pentiums BzӨ, AiHϥΤU C y{XӨo۱qW
   s} {bgLFh֭ӮP:
       ______________________________________________________________
     
   extern __inline__ unsigned long long int rdtsc()
   {
     unsigned long long int x;
     __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
     return x;
   }
       ______________________________________________________________
     
   AiH߰ݰѦҦȥHKAQnP.
   
4.2 ɶq

   QnɶT@, ϥΨ禡 time() γ\O²檺k. Qnɶ
   T, 禡 gettimeofday() jiHTL (Opeҭz| CPU Ƶ{
   vT). ܩ Pentiums Bz, ϥΤW{X_NiHT@Ӯ
   P.
   
   pGAnA椤{ (process) b@qɶFQq (get a
   signal), AoϥΨ禡 setitimer()  alarm() . Ӹ`аѦҨ禡ϥλ
   .
   
5. ϥΨL{y

   Wb C {y. LӥiHΦb C++  Objective C 
   W. ܩզXy, MAb C yIs禡 ioperm() 
   iopl() , OANiHϥ I/O ŪgO.
   
   ܩL{y, DAiHbӵ{yJզXy C y{
   XΪ̨ϥΤWһtΩIs, _hˤpg@Ӥts I/O Ω
   ɶҥݨ禡²檺 C l{Xγ\٤e, sĶAPA{
   쵲. nMNOϥΫeһ /dev/port r˸mɮ.
   
6. @ǦΪ I/O 

   `Ѥ@Ǳ` I/O 𪺵{gToǳOiHӥΪ@ت
   TTL ( CMOS) ޿Ǫ I/O .
   
   pGAnӨl]pتӨϥγoǩΨL`ΪI/O  (Ҧp, @
   몺Lμƾھ), Aӷ|ϥβ{˸mXʵ{ (Lq`Qtb֤
   ) Ӥ|pһahg I/O {. `DnOѵǷQnN
   LCD ܾ, BiF, άOLӷ~ql~ s PC з I/O 𪺤H.
   
   pGAQnjҳc檺˸mOy (wgbcF@q
   ), hݬݬO_{ Linux ˸mXʵ{.  [4]Hardware-HOWTO O
   ӦnѦҰ_I.
   
   ܩQnDhpsql˸mq(HΤ@몺qlǭz)
   Th [5]http://www.hut.fi/Misc/Electronics/ OӦnƨӷ.
   
6.1 æC (parallel port)

   æC𪺰򥻰} (HU٤ ``BASE'')  /dev/lp0 O 0x3bc , 
   /dev/lp1 O 0x378 ,  /dev/lp2 O 0x278 . pGAuOQn@ǹO
   @Lʧ@, iHѦҺ [6]Printing-HOWTO.
   
   FUYNyzзǶȿX (output-only) Ҧ, jhƪæC𳣦 `X
   R' V (bidirectional) Ҧ. ܩs ECP/EPP Ҧ (HΤ@몺
   IEEE 1284 з) f, iHѦҺ [7]http://www.fapo.com/ H
    [8]http://www.senet.com.au/~cpeacock/parallel.htm. ]bϥΪ̼Ҧ
   (user-mode) {Lkϥ IRQs  DMA, Qnϥ ECP/EPP ҦAγ\o
   g@Ӯ֤ߪ˸mXʵ{; ڷQӦHgFo˸mXʵ{, O
   ڨäD.
   
   } BASE+0 (ư) Ψӱư𪺫H (D0  D7 ON
   bits 0  7, ǪA: 0 = C (0 V), 1 =  (5 V)). @ӼgJ
   ƨӰ𪺰ʧ@|NƫHǬC (latches) b𪺸} (pins) W. @
   NӰ𪺸ŪXʧ@|NW@HзǶȿX (output-only) ҦXR
   gJҦҬCƫHŪ^, άOHXRŪXҦ qt~@ Ӹ˸mN
   }WƫHŪ^.
   
   } BASE+1 (A) OӶŪ (read-only) , |NUJH
   Ū^:
     * Bits 0 M 1 Od.
     * Bit 2 IRQ A (OӸ} (pin) , ڤDLu@z)
     * Bit 3 ERROR (1=)
     * Bit 4 SLCT (1=)
     * Bit 5 PE (1=)
     * Bit 6 ACK (1=)
     * Bit 7 -BUSY (0=)
       
   (ڤTwCǪqA.)
   
   } BASE+2 () OӶȼg (write-only)  (@ӱNӰ𪺸ŪX
   ʧ@ȷ|NW@gJƫHŪ^), ΨӱUAH:
     * Bit 0 -STROBE (0=)
     * Bit 1 AUTO_FD_XT (1=)
     * Bit 2 -INIT (0=)
     * Bit 3 SLCT_IN (1=)
     * Bit 4 Q]w 1 ɤ\æC𲣥 IRQ H (oͦb ACK }쪺
       ѧCܰ)
     * Bit 5 ΨӱXRҦɰ𪺿XJV (0 = g, 1 = Ū), oOӶȼg
       (write-only)  (@ӱNӰ𪺸ŪXʧ@惡 bit @IγB]S
       ).
     * Bits 6 and 7 Od.
       
   (P˦a, ڤTwCǪqA.)
   
   𪺸}ƦC (Pinout) 覡 (ӰO@ 25 } D rΥ~ (D-shell) 
   Ys) (i=J, o=X):
   
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 WW} 1, 14, 16, M 17 (HX) ĥιq骺}
    (open collector) Xʤ覡ݨϥ 4.7 aکi (kiloohm) ɹq
    5 V q (iyJqy 20 mA, yXqy 0.55 mA, ǪXqN
   O 5.0 V hɹqq). ѤUӪ}iyJqy 24 mA, yXqy
   15 mA, ǪXq̤p 2.4 V. CǪXqG̳O̤j 0.5 V.
   ǫD IBM W檺æCγ\|oӼз. hƽаѦҺ
   [9]http://www.hut.fi/Misc/Electronics/circuits/lptpower.html.
   
   ̫, A@ĵi: d߱aD. ڴgbq٬O}pNhs
   L] anXӨæC. oͤFoبƱAi|ıo٬OnNæC
   XDO̭n. (Aq`iH@Kyз `multi-I/O' dw˲
   G æC; unNLݭn𰱥, MNdWæC𪺰}]wb
   ŵ۪}Yi. AݦbNæC IRQ ]w, ]q`|QΨ.)
   
6.2 C (a)  (game port)

   C𪺰}d 0x200-0x207. Qn@몺a, @Ӯ֤߼h
   aXʵ{, iѦҺ}
   [10]ftp://sunsite.unc.edu/pub/Linux/kernel/patches/, ɦW joystick-*.
   
   𪺸}ƦC (Pinout) 覡 (ӰO@ 15 } D rΥ~ (D-shell) 
   Ys):
     * 1,8,9,15: +5 V (q)
     * 4,5,12: a
     * 2,7,10,14: OO BA1, BA2, BB1, M BB2 ƦJ
     * 3,6,11,13: OO AX, AY, BX, M BY ``''J
       
   +5 V }Gq`|QsDOquW, ҥHLӯѬ
   qO, o٭nݩҨϥΥDO, qѵ, HιC.
   
   ƦJΩa쪺siHAsGӾa쪺|ӫs (a A M
   a B, UGӫs) C]NOƦJ|Ӹ}. LӬO@
    TTL qǪJ, AiHqA (ѦҤU) ŪXL̪
   A. @ӹڪabsQUɷ|Ǧ^C (0 V) A_hNO
    (5V g 1 Kohm qsq}) A.
   
   ҿתJڬOq쪺ܭ. C𦳥|ӳhӮ
   (one-shot multivibrator) (@ 558 ) s|J}. C
   J}PhӮXsۤ@ 2.2 Kohm q, ӥBhӮ
   XPasۤ@ 0.01 uF ɧǹqe (timing capacitor). @
   ӹڪaCӮy (X M Y) W|@ӥiܹq, sb +5 V PC
   Ӭ۹諸J}줧 (} AX  AY Oa A Ϊ, Ӹ} BX 
   BY Oa BΪ).
   
   ާ@ɭ, hӮNX]w (5 V) åBɧǹqeWq
   F 3.3 V N۹諸X]wC. ]a줤hӮX
   ǮɶP PiܹqqȦ (]NO, ab۹yЪ
   m), pUҥ:
   
     R = (t - 24.2) / 0.011,
     
   䤤 R Oiܹqܭ (ohms)  t OǮɶP ().
   
   ]nŪXJ}쪺ƭ, AoҰʦhӮ (HgJ覡;
   ЬݤU), Mdߥ|ӮyЪHA(H򪺰ŪX覡)@HA
   ѰܦC, p䰪ǮɶP. oӫdߪʧ@O
   ۷h CPU ɶ, ӥBb@ӫDYɪhuҹO (@몺ϥΪ̼Ҧ
   (user-mode) ) Linux, ұoGOD`ǽT]ALkHTwɶӬd
   HA (DAϥή֤߼hXʵ{ӥBAobAdߪɭԧ
   _, Oo˰|Oh CPU ɶ). pGADHAN|
   O@quɶ (ƤQ@) ׷|C, AiHbdߤeIs禡
   usleep() N CPU ɶLQn檺{ (processes).
   
   C𤤰ߤ@ݭnAӦs}O 0x201 (L}Oʧ@@˴NO
   S). oӰ}ҰgJʧ@ (קAgJ) |ҰʦhӮ
   . oӰ}ŪXʧ@|^JHA:
     * Bit 0: AX ( (1=) hӮXA)
     * Bit 1: AY ( (1=) hӮXA)
     * Bit 2: BX ( (1=) hӮXA)
     * Bit 3: BY ( (1=) hӮXA)
     * Bit 4: BA1 (ƦJ, 1=)
     * Bit 5: BA2 (ƦJ, 1=)
     * Bit 6: BB1 (ƦJ, 1=)
     * Bit 7: BB2 (ƦJ, 1=)
       
6.3 C (serial port)

   pGAһ˸mO䴩@ǹO RS-232 F, AӥiHpA@a
   ϥΦC. Linux ҴѪCXʵ{ӯΦba (A
   ݭngC{, άO֤ߪXʵ{); L۷㦳qΩ, ҥH
   OϥΫDзǪ bps tvHΨLӤOD. аѦ termios(3) 
   , CXʵ{l{X (linux/drivers/char/serial.c), Hκ
   [11]http://www.easysw.com/~mike/serial/index.html Whb Unix @~
   tμgC{.
   
7. 

   pGAQnn I/O ~, AiHbæCWۦո ADC B/ DAC 
   (: q, iϥιCWαNΨ쪺ϺйqsY ߤ
   ~, pGA˸m\vӧChiHæCӥRq, MNOϥΥ~
   qѵ), άOR AD/DA d (j«/Ct~i I/O 
   ). Ϊ̬O Linux ĥdXʵ{Ҥ䴩Kyĥd (t٬۷) W
   1  2 ӤT, (i|) LkksHqDAӨNF.
   
   ϥκT˸m, aiyXJH~t. pGAo
   譱g, Ai|եHXӹj (qPA˸m Ҧ H
   ) qlzZ. յ۱qqWoXq (bWΨ쪺H}i
   HѨq) HDF̨ΪjĪG.
   
   pGA{bbMb Linux WϥΪLqO]pn, @Ӻ٬
   Pcb KO X11 ε{ӯӥ, unAn@Ǥӽ. \h
   Linux o檩 (distributions) toӵ{, PɥL]Qb}
   [12]ftp://sunsite.unc.edu/pub/Linux/apps/circuits/ W(ɦW pcb-*).
   
8. Dư

   Q1.
          ڦs I/O ɵGI segmentation faults oӰD
          
   A1.
          OA{S root v, NO]YǲzѾɭP禡 ioperm() I
          s. ˬd禡 ioperm() Ǧ^. P, ˬdAҦs]NO
          AH 禡 ioperm() ұҥΪ} (Ѧ Q3). pGAϥΪO
          ɶO (inb_p(), outb_p(), ), Oo]nIs禡
          ioperm() HKs} 0x80.
          
   Q2.
          ڵLk in*(), out*() 禡QwqbB, P gcc ]Ѧ
          쥼wqŸ (undefined references).
          
   A2.
          AbsĶ{ɨS}̨Τƿﶵ (-O), ] gcc ѪR
          asm/io.h O. άOAڥNSϥ #include
          <asm/io.h>.
          
   Q3.
          out*() Sʧ@, άOʧ@ǩǪ.
          
   A3.
          ˬdѼƩҩm; LӬOo outb(value, port) , ӤO
          MS-DOS W`Ϊ outportb(port, value)
          
   Q4.
          ڷQn@ӼзǪ RS-232 ˸m/sæC𪺦L/a...
          
   A4.
          A̦nఱƦӨϥβ{Xʵ{ (L̦sb Linux ֤ߤ
           X AΨLa) ӹFAؼ. oXʵ{q`۷
          qΩ, ҥHNOIзǪ˸m, L̳q`ॿ`B@. o
          з I/O 𪺬TаѦҫeL.
          
9. {Xd

   oO@qΨӦs I/O ²檺{Xd:
       ______________________________________________________________
     
/*
 * example.c: @ӥΨӦs I/O 𪺫D`²檺d
 *
 * oӵ{XèSγB, LuOF𪺼gJ, Ȱ,
 * HΰŪXXӰʧ@. sĶɽШϥ `gcc -O2 -o example example.c',
 * åH root  `./example'.
 */

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

#define BASEPORT 0x378 /* lp1 */

int main()
{
  /* o}sv */
  if (ioperm(BASEPORT, 3, 1)) {perror("ioperm"); exit(1);}

  /* ]w𪺿XƫH (D0-7) s (0) */
  outb(0, BASEPORT);

  /* 𮧤@U (100 ms) */
  usleep(100000);

  /* qA (BASE+1) ŪXƨܵG */
  printf("status: %d\n", inb(BASEPORT + 1));

  /* ڭ̤Aݭnoǰ} */
  if (ioperm(BASEPORT, 3, 0)) {perror("ioperm"); exit(1);}

  exit(0);
}

/*  example.c */
       ______________________________________________________________
     
10. P

   ULڪHbӦhLk@@CX, ٬OnU컡nh¤F. ҦӫH
   UڪHèS@@^ЭPWpN, æA§A̪U.

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/
