리눅스에서 프린터를 일반 포트처럼 제어하기 위해서는 리눅스용 디바이스 드라이버를 만들어야 합니다.
하지만 기본적으로 지원하는 디바이스드라이버가 있다면 굳이 프로그램을 짤 필요는 없습니다.
여기서는 리눅스에서 기본적으로 지원하는 /dev/port 디바이스파일을 이용하여 간단하게 포트에 데이터를 전송하고자 합니다.
참 여기서 디바이스, 디바이스 드라이버, 디바이스파일 이라는 단어가 어렵게 느껴지시는 분들을 위해 잠깐 정의하고 넘어가겠습니다.
디바이스[device]는 말그대로 하드웨어 장치를 말합니다.
디바이스드라이버[device driver]는 위에서 말한 디바이스, 즉 하드웨어장치를 제어하는 프로그램을 드라이버라 합니다.
드라이버파일[driver file]은 드라이버가 리눅스에 올라가있는것을 호출하기 위한 정보가 들어있는 파일입니다.
이 드라이버파일을 어플리 케이션 프로그램에서 open한 후 사용하게 됩니다.

본 실험에서는 CentOS4.4 리눅스 커널 2.6.9 환경에서 실험 했으므로 독자 분들도 같은 환경에서 해보시기를 바랍니다.
다른 커널에서 꼭 않된다는 이야기는 아니지만 혹시 않될수도 있으니 되도록이면 같은 서버에서 하는것이 좋을듯 합니다. 
리눅스 커널 확인
   $uname -a
       Linux 2.6.9

이제 서버에 아래와 같은 프로그램을 작성합니다.

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char **argv)
{
  int fd;       // File Descripter
  unsigned char buff[1];                       
  fd = open("/dev/port", O_RDWR);     
  if(fd < 0)                                            
  {
        perror("/dev/port open error");
  }
  while(1)      
  {
          lseek(fd, 0x378,0);       // file 포인터를 0x378 번지로 합니다. 프린터포트 1의 절대번지입니다.
          buff[0] = 0x55;               // 버퍼에 0x55를 넣습니다.
          write(fd, buff, 1);            // 위에서 정의한 /dev/port+0x378 포인트에 buff의 데이터 1바이트를 write(출력)합니다.
          sleep(1);                        // 1초 지연

          lseek(fd, 0x378,0);       // file 포인터를 0x378 번지로 합니다. 프린터포트 1의 절대번지입니다.
          buff[0] = 0xaa;               // 버퍼에 0xaa를 넣습니다.
          write(fd, buff, 1);            // 위에서 정의한 /dev/port+0x378 포인트에 buff의 데이터 1바이트를 write(출력)합니다.
          sleep(1);                        // 1초 지연
  }
  close(fd);
  return 0;
}
이렇게 하면 프린터포트의 데이터포트로 0X55와 0XAA가 번갈아 출력됩니다.

이제 위에 작성한 프로그램을 io.c 로 저장한 후 서버에 업로드 한다음
$gcc io.c
를 실행하면 컴파일을 하여 a.out이 만들어 집니다. a.out을 실행하면 프린터 포트로 출력이 나갑니다.
$./a.out

참고로 0x55=01010101
이고     0xaa=10101010
입니다.

직접 확인하기 위하여 간단한 회로를 만들었습니다.
led를 포트 8개에 모두 붙이면 좋겠지만 귀찮아서 그냥 2개만 붙였습니다.
시간이 되시면 같은 방법으로 8개를 모두 붙여서 실험해보세요.
1.jpg
2.jpg








참고
디바이스 port 의 절대번지 정의는 아래와 같습니다.
$ cat /proc/ioports
0000-001f : dma1
0020-0021 : pic1
0040-005f : timer
0060-006f : keyboard
0080-008f : dma page reg
00a0-00a1 : pic2
00c0-00df : dma2
00f0-00ff : fpu
0170-0177 : ide1
01f0-01f7 : ide0
02f8-02ff : serial
0330-0333 : MPU-401 UART
0376-0376 : ide1
0378-037a : parport0
03c0-03df : vga+
03f6-03f6 : ide0
03f8-03ff : serial
0400-040f : 0000:00:07.4
0778-077a : parport0
0c00-0c7f : 0000:00:07.4
0cf8-0cff : PCI conf1
5000-50ff : 0000:00:07.4
9000-9fff : PCI Bus #01
cc00-ccff : 0000:00:0f.0
cc00-ccff : 8139too
d000-d01f : 0000:00:07.2
d000-d01f : uhci_hcd
d400-d403 : 0000:00:07.5
d400-d403 : via82cxxx_audio
d800-d803 : 0000:00:07.5
d800-d803 : via82cxxx_audio
dc00-dcff : 0000:00:07.5
dc00-dcff : via82cxxx_audio
ffa0-ffaf : 0000:00:07.1
ffa0-ffa7 : ide0
ffa8-ffaf : ide1
리눅스에서 정의된 포트를 이용하기 위해서는 디바이스를  /dev/port 을 사용하면 됩니다.

ibm-pc 프린터포트 어뎁터 내부회로
lpt.jpg