TL;DR

  • DOS에는 시스템 가동 시간을 명시적으로 추적하는 기능이 없어, 여러 방식의 신뢰성과 한계를 비교한 결과 _dos_getftime(0, ...) 방식을 사용함.
  • Pascal 프로그램 UPTIME.PAS는 NUL이 아니라 표준 입력(stdin)의 수정 시각을 읽는 것으로 보이며, ctty 사용 시 값이 재초기화되는 문제가 있음.
  • UPTIMEC는 CMOS(Complementary Metal-Oxide-Semiconductor)와 RTC(Real-Time Clock)에 알람 시각을 저장해 가동 시간을 계산하지만, 부팅 시 /R 옵션으로 초기화해야 정확함.
  • BIOS 인터럽트 INT 1A,0은 자정 이후의 초 또는 부팅 이후의 초를 반환할 수 있지만, 자정 플래그를 재설정해 DOS 날짜 처리에 영향을 줄 수 있음.
  • 부팅 시각을 파일에 기록하는 방식은 파일 시스템을 사용하고 비용이 더 들지만, 가장 견고하고 이식성이 높을 가능성이 있음.

Pascal 버전과 NUL(이라고 알려진 것)

  • Mark Aitchison의 UPTIME.PAS는 저장소의 .timestamps 파일을 기준으로 1997년경 작성된 것으로 보임.
  • 프로그램은 Pascal의 assign(fyle, 'NUL')과 GetFTime(fyle, t)를 사용함. 처음에는 이를 NUL 파일을 열어 수정 날짜와 시각을 읽는 동작으로 해석할 수 있음.
  • OpenWatcom v2의 _dos_getftime()을 이용해 NUL을 열고 수정 시각을 읽는 C 프로그램을 작성하면 현재 날짜와 시각만 출력됨. 반면 Aitchison의 프로그램은 가동 시간을 출력함.
  • Pascal의 assign()은 프로그램 내부의 관리 데이터만 다루며, 즉시 관찰할 수 있는 효과가 없고 실제로 파일을 여는 동작도 아님.
  • 디버거로 확인한 결과 Aitchison의 프로그램은 INT 21,57을 호출하면서 BX 레지스터를 0으로 설정함. 이를 바탕으로 NUL이 아니라 표준 입력(stdin)의 수정 시각을 읽는 것으로 결론 내림.
  • C 프로그램에서 파일 핸들 0을 _dos_getftime(0, &raw_date, &raw_time)에 전달하면 같은 INT 21,57 호출이 발생하고 가동 시간이 출력됨.
  • DOSSHELL에서 새 명령 프롬프트를 열어도 값은 올바르게 유지되지만, ctty로 콘솔을 전환하면 표준 입력의 타임스탬프가 재초기화됨.
  • 처음 A:\uptime 실행 시 가동 시간은 3분 37초임.
  • ctty com1로 직렬 콘솔로 전환한 뒤에는 5초로 표시됨.
  • ctty con으로 VGA 콘솔에 돌아온 뒤에는 2초로 표시됨.
  • DOSBox에서는 이 방식이 작동하지 않고 의미 없는 값이 출력됨. Windows나 OS/2에서 DOS 버전을 실행해도 비슷한 문제가 발생하지만, 해당 운영체제용 전용 버전이 있음.

CMOS / RTC 버전

  • FreeDOS 저장소의 Javier Gutierrez Chamorro가 만든 UPTIMEC는 2017년 버전이며, DOS의 시간 기능을 우회해 CMOS/RTC에 직접 접근함.
  • 프로그램은 실행 시 현재 시각과 알람 시각을 CMOS/RTC에서 읽고, 알람 시각이 설정되지 않았다면 현재 시각을 알람 시각으로 저장한 뒤 두 시각의 차이를 시스템 가동 시간으로 표시함.
  • 최초 실행 시 알람 시각이 설정되지 않았다면 가동 시간이 거의 0으로 표시될 수 있음. 이후 실행에서는 ctty 전환에 영향을 받지 않고 값을 표시함.
  • 참고 자료: CMOS, CMOS RAM.
  • 이 방식은 쉽게 깨지지 않는다는 점에서 더 나을 수 있지만, 초기 설정이 필요함. Dell Inspiron 6400에서 부팅 직후와 전원이 꺼져 있던 뒤 실행했을 때 가동 시간이 2분으로 표시됐으며, 이는 CMOS 값이 재부팅과 전원 차단 후에도 유지되기 때문임.
  • 올바른 사용법은 autoexec.bat에서 uptime /R을 실행하는 것임. 이 명령은 CMOS에 저장된 값을 현재 시각으로 초기화하고, 이후 명령행에서 실행할 때 정확한 가동 시간을 표시하게 함.

‘시스템 시계 카운터’ 읽기

  • 웹 검색에서 찾은 StackOverflow 답변은 INT 1A,0 호출을 제안함.
  • 해당 답변은 관련 페이지의 설명을 인용함. BIOS INT 1A로 시스템 시각, 즉 현재 타이머 틱 값을 요청하면 자정 플래그도 반환하고 동시에 초기화함.
  • BIOS 함수는 DOS 날짜를 갱신하지 않으므로 이후 날짜를 요청해도 올바르게 갱신되지 않을 수 있음. DOS 함수는 자정 플래그를 올바르게 유지하지만, BIOS INT 1A를 직접 호출하는 프로그램은 플래그가 설정돼 있었는지 확인하고 필요하면 다시 설정해야 함.
  • 간단한 시험과 HelpPC 설명에 따르면 이 호출은 자정 이후의 초를 반환함. StackOverflow 답변은 INT 1A,1로 시각을 설정한 적이 없다면 부팅 이후의 초가 반환된다고 설명하지만, 실제 시험에서는 이미 누군가 또는 무언가가 시각을 설정한 것으로 보임.

단순한 방법

  • UPTIMEC처럼 부팅 시 uptime /R을 실행해야 한다면, CMOS를 다루는 대신 부팅 시각을 파일에 기록하고 이후 실행에서 현재 날짜와 시각을 파일의 값과 비교할 수 있음.
  • 이 방식은 파일 시스템을 어지럽히고 비용이 가장 많이 들 수 있지만, 가장 견고하고 이식성도 가장 높을 가능성이 있음.

결론

  • DOS용 도구에서는 _dos_getftime(0, ...) 방식을 선택함.
  • 별도의 설정이 필요하지 않음.
  • 읽기 전용 동작임.
  • 필요한 용도에는 충분해 보임.
  • 가동 시간을 확인할 일은 가끔뿐이며, 실제로 꼭 필요한 기능도 아니고 단순한 호기심에 가까움.
  • 더 낫거나 다른 방법이 있다면 제안 요청함.