ftape
이것은 원래 Bas Laarhoven에 의해 개발되었고, 이후 Claus-Justus Heine 등이 개발했으며, 현재는 my (Dmitry Brant)의 추가적인 수정과 현대화를 거쳐 최신 Linux 커널(버전 6.1 이상)에서 컴파일하고 실행할 수 있도록 개선된 ftape 드라이버의 개발 연속물입니다.
요약: 완벽하게 작동합니다! (Xubuntu 24.04 및 26.04 (x86_64), Debian 12.12 (i386)에서 테스트 완료)
하지만 여전히 많은 테스트가 필요하며, 따라서 현대화 노력과 관련된 버그가 남아 있을 수 있습니다. 완전히 원래의(수정되지 않은) 드라이버를 CentOS 3.5 (커널 버전 2.4.21)에서 작동시키기 위한 이전 작업에 대해서는 이 저장소의 centos35 브랜치와 그 안에 있는 README를 참조하십시오.
지금까지의 이야기
Ftape은 Linux가
하지만 그것이 전부는 아닙니다:
- 커널에 포함되었던 마지막 버전의 드라이버는 제거되기 직전까지 3.04 버전이었습니다.
- 하지만 저자는 커널 릴리스와 독립적으로 드라이버 개발을 계속했습니다. 실제로, 이 드라이버의 마지막 알려진 버전은 2000년의 4.04a였습니다.
- 제 목표는 마지막 공식 릴리스로부터 25년이 지난 지금도 현대적인 커널 버전을 위해 이 드라이버를 유지보수하는 것입니다.
개발 동기 (Motivation)
QIC 테이프가 백업 매체로 오랫동안 쓸모없게 되었음에도 불구하고, 야생에 남아있는 이러한 테이프들로부터의 데이터 복구(data recovery) 시장은 여전히 중요하며, ftape 드라이버가 중요한 틈새시장을 채울 수 있습니다. 또한, 오래된 하드웨어를 다시 활성화하는 데 도움을 줄 수 있는 레트로 컴퓨팅 커뮤니티도 존재합니다.
목표 (Goals)
- 이 드라이버는 주로 오래된 카트리지에서 데이터를 복구하기 위한 것이므로, 다양한 테이프 드라이브와의 호환성을 강조하며 읽기(reading) 기능 유지에 더 중점을 둘 것입니다. _쓰기(writing)_와 관련된 버그는 우선순위가 낮아질 수 있으며, 실제로 쓰기/포맷 기능을 완전히 제거하고 별도의 비유지보수 브랜치에 남길 수도 있습니다.
- 이 드라이버를
빌드 프로세스가 완료되면, 저장소의 기본 폴더에 여러 개의 커널 모듈(.ko 파일)이 생성되어야 합니다. 이 모듈들은 insmod 또는 modprobe를 사용하여 로드할 수 있는 모듈입니다. 실제로 make install(모듈을 실제 /lib/modules/... 디렉터리로 복사하는 과정)을 실행할 필요는 없으며, 저는 그저 필요할 때 저장소 디렉터리에서 직접 모듈을 로드하는 것을 선호합니다.
편의를 위해, 특정 유형의 드라이브에 맞는 적절한 매개변수와 순서로 모듈을 로드하기 위한 스크립트들이 제공됩니다. (매개변수의 예시 및 설명은 이 스크립트들을 참고하십시오):
insert_floppy.sh: Colorado 250 등 플로피 컨트롤러(FDC)에 드라이브가 연결된 경우 사용합니다.
insert_max.sh: Ditto Max 드라이브, 특히 플로피 컨트롤러에 연결된 경우 사용합니다.
insert_parallel.sh: 병렬 포트에 드라이브가 연결된 경우 사용합니다. 이 스크립트는 로드 시 경고를 표시할 수 있지만 무시하고 dmesg에서 드라이버의 실제 상태를 확인하십시오. (그리고 BIOS에서 병렬 포트가 ECP로 구성되었는지 확인하십시오.)
이 모든 과정이 완료되고 커널 모듈들이 오류 없이 로드되면, /dev/nqft0, /dev/rawqft0 등과 같은 테이프 장치 파일들과 상호 작용할 수 있습니다. 다음과 같은 명령어를 사용하여 테이프에서 데이터를 덤프할 수 있습니다: dd if=/dev/nrawqft0 of=out.bin bs=10240
Raw 모드
Raw 모드는 카트리지의 데이터를 보존하기 위해 덤프하는 것을 권장하는 방식입니다.
Raw 장치( /dev/rawqft0, /dev/nrawqft0)가 읽기 전용으로 열리면, 드라이버는 모든 세그먼트에 대한 축약되지 않은 이미지(unabridged image)를 제공합니다. 즉, 29개의 데이터 섹터와 그 뒤에 오는 3개의 ECC 섹터 전체, 정확히 테이프에서 읽힌 그대로입니다. 이로 인해 덤프된 데이터는 카트리지의 완벽하게 충실한 표현이 됩니다. (나쁜 섹터를 포함하는 세그먼트는 나쁜 섹터 맵(bad sector map)에 나열된 대로 그만큼 짧습니다. 왜냐하면 해당 섹터들은 테이프에 존재하지 않기 때문입니다.)
ECC 검사 및 수정은 이전과 동일하게 발생하며, 수정된 세그먼트는 수정된 형태로 덤프됩니다. ECC 오류가 발생하는 세그먼트도 여전히 덤프되기를 원한다면 ft_ignore_ecc_err 모듈 매개변수를 사용하십시오. (raw 장치가 _쓰기용_으로 열리는 경우, ECC 섹터는 데이터 스트림의 일부가 아닙니다(드라이버가 쓰는 동안 자체적으로 생성함). 이 경우 0x7400 바이트/세그먼트의 이전 동작이 적용됩니다. 이는 사용자 버퍼가 29kb로 지정된 MTIOCRDFTSEG ioctl에도 동일하게 적용됩니다.)
게다가, raw 모드는 테이프의 맨 처음에 나타나는 헤더 세그먼트(들)도 덤프합니다(이전 버전의 ftape는 볼륨 테이블로 시작하는 데이터 세그먼트만 덤프했습니다). 헤더 세그먼트는 테이프의 포맷팅 상세 정보와 배드 섹터 맵, 기타 메타데이터를 포함합니다. 이는 덤프에 인코딩된 모든 오프셋이 덤프의 시작점(시작)이 아닌 첫 번째 데이터 세그먼트(VTBL 세그먼트)를 기준으로 상대적이라는 것을 의미합니다.
이 모든 것은 테이프의 100% 완전한 이미지를 확보하기 위함이며, 단순히 적절한 아카이빙뿐만 아니라, 에뮬레이션된 DOS 또는 Linux 환경이 에뮬레이션된 QIC 드라이브와 통신하고, 덤프된 테이프 이미지를 에뮬레이션 카트리지로 사용하는 잠재적인 에뮬레이션 목적을 위해서입니다.
이는 또한 raw 테이프 이미지를 다룰 때 몇 가지 함의를 만듭니다:
- raw 이미지를 파싱할 때는 각 세그먼트 끝에 있는 ECC 섹터를 고려하거나(또는 무시하고) 기억해야 하며, 볼륨 테이블 이전에 오는 헤더 세그먼트도 고려해야 합니다.
- 만약 raw 이미지를 새로운 물리적 테이프로 _쓰기_로 되돌리고 싶다면, 드라이버가 그 요소들을 자체적으로 추가할 수 있도록 헤더 세그먼트와 ECC 데이터를 제거(strip away)해야 합니다.
Bare mode
Bare 모드는 드라이브에 직접 통신하기 위한 것이며, 이 경우 드라이버는 완전히 개입하지 않습니다. bare 장치(/dev/xrawqft0)가 열리면, 드라이버가 플로피 컨트롤러를 점유하고 다른 작업은 전혀 하지 않습니다.
이러한 파일 디스크립터로 할 수 있는 유일한 작업은 MTIOCFTCMD ioctl을 발행하는 것입니다. 즉, 임의의 QIC-117 명령을 드라이브로 전송하고 임의의 결과 비트를 읽어오는 것입니다. read(), write() 및 다른 모든 ioctl은 -EACCES를 반환합니다. 이는 드라이버의 일반적인 초기화로는 대응할 수 없는 동작을 하는 드라이브를 실험하거나, 벤더별 특정 명령을 리버스 엔지니어링하는 데 사용됩니다.
Bare mode는 raw 모드와 no-rewind를 의미하며, 드라이버 상태에 흔적을 남기지 않습니다. 드라이버가 프로그램이 드라이브에 어떤 작업을 했는지 알 수 없기 때문에, /dev/qft0 등의 다음 일반적인 열기는 웨이크업 방법을 재감지하고 드라이브를 처음부터 다시 초기화합니다.
임의의 QIC-117 명령 전송 (ftapecmd)
tools/ 디렉터리에는 완전히 임의의 QIC 명령을 드라이브로 전송하는 작은 유저스페이스 유틸리티가 포함되어 있습니다:
make tools
sudo ./tools/ftapecmd -f /dev/nrawqft0 -c 20
명령은 숫자로 (-c 20, -c 0x14) 또는 이름으로 (-c "report drive status") 제공할 수 있으며, ftapecmd --list는 드라이버가 알고 있는 모든 명령을 출력합니다. 다른 옵션:
-p 3,4: 명령어 다음에 최대 세 개의 매개변수(nibble, 0-15)를 전송합니다.
-b 8: 주어진 비트 수의 결과를 읽어오는데, 이는 report 명령이 데이터를 반환하는 방식입니다 (에러 코드를 보고하려면 -b 16을 사용하세요).
-w 5000 / -a 5000: 명령어 전/후로 드라이브가 준비될 때까지 최대 주어진 밀리초(ms)만큼 기다리고, 그 결과로 얻은 드라이브 상태를 보고합니다.
-r: 먼저 드라이버를 raw 모드로 전환하고(MTIOCFTMODE), -n은 건식 실행을 수행하여 드라이브에 손대지 않고 전송될 내용을 출력합니다.
기억해야 할 몇 가지 사항이 있습니다:
- 이 ioctl은 드라이버가 raw 모드일 때만 작동합니다. 그래서 예제에서는 raw 장치 노드(
/dev/rawqft0, /dev/nrawqft0)를 사용합니다. -r 옵션은 이미 드라이버가 normal 모드로 설정된 경우에 대비한 것입니다.
- 이 도구는 부적절하게 사용될 경우 위험할 수 있습니다: 예약되었거나, 정의되지 않았거나, 테이프에 잠재적으로 파괴적인 명령을 전송할 수 있습니다. 임의로 무언가를 보내기 전에 QIC-117 spec를 참조하십시오.
일부 예시:
# 드라이브의 상태를 요청하고, 상태 비트를 디코딩합니다
sudo ./tools/ftapecmd -c "report drive status" -b 8
...
문제 해결 (Troubleshooting)
dmesg을 적극적으로 사용하고 그 안에 있는 로그 메시지들을 확인하십시오. ft_tracings 모듈 파라미터를 사용하여 메시지의 상세도를 높여서 어떤 문제가 있는지 좁혀나가십시오.
플로피 컨트롤러 (Floppy controller)
BIOS에서 플로피 컨트롤러가 활성화되어 있는지 확인하십시오. 일부 BIOS에서는 최소한 하나의 플로피 드라이브(크기/용량은 상관없음)를 활성화하는 것을 의미합니다.
/proc/ioports와 /proc/interrupts를 확인하여 시스템이 어느 IO 포트와 인터럽트를 플로피 컨트롤러에 할당했다고 생각하는지 보고, ftape-internal을 로드할 때 그 할당(기본값과 다를 경우)을 파라미터로 사용하십시오. 시스템이 부팅될 때, floppy 모듈이 자동으로 로드되면서 해당 리소스를 독점합니다. 이것이 바로 이 저장소의 insert_floppy.sh 스크립트가 ftape 모듈을 로드하기 전에 명시적으로 floppy 모듈을 언로드하여, 해당 리소스들이 먼저 해제되도록 보장하는 이유입니다.
병렬 포트 (Parallel port)
BIOS에서 병렬 포트가 EPP 또는 ECP 모드로 구성되어 있는지 확인하십시오.
/proc/ioports를 확인하여 IO 포트가 parport 모듈에 할당되었는지 확인하십시오. ftape는 parport API를 사용하여 병렬 포트에 접근하므로, 병렬 포트를 사용하기 위해 ftape에 사용자 정의 파라미터를 전달할 필요는 없습니다. 따라서 parport 자체가 제대로 작동하는지 확인하는 것이 중요합니다.
면책 조항 (Disclaimers)
- 이 드라이버는 32비트 또는 64비트 x86 아키텍처 모두에서 작동해야 하지만, 명백히 이전과 마찬가지로 동일한 제한된 FDC 칩셋 세트와만 작동합니다. 실제 FDC 테이프 드라이브를 사용하려면 해당 드라이브를 지원되는 FDC가 있는 마더보드에 연결해야 합니다.
- 현대화되지 않은 유일한 부분은 레거시 플러그 앤 플레이(Plug-and-Play) 지원입니다 (makefile에서
internal/fdc-isapnp.c는 제외됨). 이는 제가 테스트할 PnP 카드/장치가 없기 때문입니다. 만약 그러한 장치를 가지고 계시다면, 언제든지 연락 주시거나 이 드라이버를 가져가서 작동하도록 시도해 보신 후 풀 리퀘스트(pull request)를 제출해 주세요.
- 저는 테스트와 실험을 위한 다소 제한적인 테이프 드라이브 컬렉션을 가지고 있기 때문에, 이 드라이버가 사용자의 시스템에서 작동할 것이라고 보장하지 않습니다. 만약 이 드라이버로 작동하지 않는 드라이브를 가지고 있거나, 단순히 QIC 테이프에서 데이터를 복구해야 한다면 연락 주세요!**