2012년 10월 2일 화요일

ATA 이야기1

ATA와 ATAPI라는 말을 혹시 들어본 적이 있습니까? 꼭 "도를 아십니까?"라는 말과 비슷한 느낌을 풍기는 군요...
 대학교를 9년이나 다녔고 자칭 뼛속 깊은 공대생에 programming을 공부하며 지낸 저도, 입사하고 처음 들어본 말이었습니다. ATA spec.은 양도 꽤 많고 전부 영어로 되어 있어, 입사하고 한참을 ATA spec. 문서를 읽고 또 읽으며 이해하려 노력해야 했었습니다. 지금이야 이렇게 ATA에 관련된 내용의 글을 쓸 수 있게 되었지만, 그 때는 정말 마법의 언어였었습니다.
 처음 질문으로 돌아가서, ATA라는 것은 Advanced Technology Atatchment의 약자로 저장 장치와의 통신을 위하여, 주요 HDD 제조 업체 및 표준제정 집단에서 만들어진 일종의 protocol 문서입니다. 제가 생각하는 spec 탄생에 대한 대강의 역사는 흔히 computer라 불리는 기기에 쓰이는 보조 기억 장치 기기들이 여러 종류 등장하게 되고, 각종 저장 장치들과의 통신하는 방법이 각양각색이라 이를 통합 및 표준화하고자 만들어진 것이 ATA spec의 시초일 것 같습니다. 현재 남아있고 또 쉽게 찾아볼 수 있는 ATA 장치라고 하면 HDD, SSD, CD-ROM 장치 정도가 되겠습니다. ATA에서는 저장 장치류를 구분할 때 removable과 그렇지 않은 녀석으로 구분합니다.위의 세 가지는 non-removable이고 removable의 대표적인 예는 USB 장치가 있습니다. 그렇습니다. ATA 장치라 함은 곧 저장 장치를 뜻하는 것으로 이해하면 될 것 같습니다.
 그럼 ATAPI는 무엇일까요? ATA with Packet Interface 장치를 말합니다. CD-ROM 장치나 SCSI 장치 등Packet Interface를 사용하는 장치들의 지원을 위해 추가된 내용을 말합니다.  ATA에서 저장 장치와 통신하는 interface 방식은 PATA와 SATA 두 가지 방식이 있습니다.
 PATA는 전송 속도의 한계가 존재하기에, 현재 고용량화되어 전송 속도가 한계치를 넘어버린 2.5" HDD 이상에서는 거의 쓰이지 않습니다. 아주 드문 경우로 전력 소모가 굉장히 중요한 요소가 되는 장치에서는 가끔 쓰이는 경우가 있고, 전송 속도가 중요하지 않는 소형 HDD에도 사용되고 있긴 하나 이젠 구시대의 유물로 처리되는 분위기입니다. 중요한 걸 빠트렸군요. PATA는 Parallel ATA의 약자로 병렬 방식으로 통신하는 것을 뜻합니다.
 SATA는 Serial ATA로 직렬 방식의 interface로 PATA의 전송 속도 한계를 극복하고자 만들어진 것입니다. 물론 전송 속도 외에 SATA 만이 가지는 고유한 명령어나 power management를 위한 몇 가지 방식이 도입되기는 했으나, 일반인이 이해하기에 PATA와의 차이점은 통신 방식과 전송 속도의 차이면 충분할 것 같습니다. SATA가 대세가 되어버린 지금, 기술도 많이 발전하여 어느새 3.0까지 나왔습니다. 각각의 version 별로 조금씩 추가되고 발전된 내용이 있긴 하지만 간단하게 말하자면, 1.0은 1.5Gb/s, 2.0은 3.0Gb/s, 3.0은 6.0Gb/s 이런식으로 지원하는 전송 속도가 뒤로 갈 수록 빨라지게 됩니다. SATA는 별도의 spec이 존재할만큼 그 내용이 방대하기에 나중에 따로 다루도록 하겠습니다.
 이 글에서 뿐만 아니라 앞으로 이어질 글에서도, 자료형의 정의는 아래와 같습니다. 보통 word라는 녀석은 chip에 많이 의존하는데 spec이 만들어졌을 때 16bit chip을 썼나 봅니다. 그리고 아직도 16bit입니다.
  - Byte : 8bit
  - WORD : 16bit = 2 bytes
  - DWORD : 16bit = 2 words = 4 bytes

 ATA spec의 주 내용 중 거의 70%는 command에 관련된 내용이니, command가 어떻게 나가고 그에 대한 응답을 어떻게 받는지를 먼저 알 필요가 있겠습니다. ATA에서 I/O의 가장 기본이 되는 것은 바로 Task File Register(이하 TFR) 입니다. TFR의 구성은 command의 종류에 따라 다지만 기본 구성은 아래와 같습니다.
원래는 TFR이라는 용어가 없는데, 제가 Task File Register를 계속 쓰려하니 귀찮아서 만든 약어입니다. 전체적인 TFR set의 구성은 아래 그림과 같습니다.
 28bit command의 경우 1 byte 크기를 가지는 7개의 register를 사용하고, 48 bit의 경우 2 byte 크기를 가지는 register 5개와 1 byte 크기를 가지는 register 2개를 사용합니다. 뭐 결국 크기만 다르지 TFR의 개수는 동일하다고 보면 됩니다. 아래 그림은 각각의 경우에 대한 TFR이 어떻게 구성되는지에 대한 것입니다.
 

[28bit Read DMA command에 대한 TFR 구성] 
[48bit Read DMA Extended command에 대한 TFR 구성]
 맨 처음 그림(I/O registers)에 보이는 것과 실제 command를 보낼 때의 사용을 보면 한 녀석이 비는 것을 찾으셨나요? 빠진 녀석은 Data register인데 이는 DATA I/O coomand에서 실제 어떤 data를 I/O할 것인지에 대한 정보를 담고 있는 녀석입니다. Non-data command에서는 이 녀석을 사용하지 않습니다.
 그럼 28bit command와 48bit command는 무엇일까요? 초기에 저장 장치는 용량이 작아서 28bit면 모든 영역에 대하여 주소 지정을 할 수가 있었습니다. 28bit면 128GB까지 주소 지정을 할 수가 있습니다. 그러다 몇 년 전부터 128GB를 넘는 HDD가 쏟아져 나오기 시작하면서부터 28bit command로는 128GB를 넘는 영역에 대하여 access를 할 수 없게 됩니다. 이 문제를 해결하기 위하여 48bit command가 만들어졌고 이들을 위한 TFR set이 추가되게 됩니다. 간단하게 48bit command는 128GB보다 더 큰 용량을 가지는 저장 장치를 처리하기 위한 command인 것입니다. 48bit를 가지고 처리할 수 있는 용량은 128PB 까지입니다. 감이 안오시나요? 128PB = 131072TB = 134217728GB가 됩니다. 현재 2TB의 3.5" HDD가 막 개발되어 양산 준비 중인 것을 보면 한동안은 48bit로도 충분할 것으로 보입니다. 여기서 예리하신 분은 어떻게 위의 용량이 나오게 됐는지 궁금하실 겁니다. 28bit를 가지고 계산하면 256M까지 밖에 나오지 않는데 어떻게 128GB가 되는 것일까요? 그 이유는 각각의 bit는 각각의 sector를 가르키기 때문입니다. 그럼 sector는 뭘까요? sector라는 것은 HDD에 access할 때 최소 단위이고 그 크기는 현재 일반적인 기준으로 512bytes입니다. 즉 256M * 512bytes = 128GB가 되는 것입니다. 잠시 딴 이야기를 해보자면 과거 1 sector = 512 bytes라는 인식이 지배적이었습니다. 그러나 HDD도 용량 늘리기의 한계에 부딛혔는지 sector 크기를 늘리기 시작하고 있습니다. 실제로 Western Digital의 경우 sector 크기를 늘린 새로운 sector 크기에 대하여 뭔가 신기술인 마냥 언론에 홍보를 시작하더군요. 왜 sector 크기를 늘리면 용량 확보에 유리한지에 대한 이유는 시간이 되면 설명드리고 일단은 현 추세가 그렇다는 것입니다. 이렇게 sector 크기를 늘린 것에 대해 super sector 또는 multi-sector라는 용어를 사용하고 있습니다. 그러나 문제는 이렇게 sector 크기를 늘리더라도 Windows XP에서는 해당 HDD를 사용할 수 없습니다. OS에서 지원하지 않기 때문이죠. Vista 이상의 상위 version에서는 지원하도록 돼있습니다. Linux 계열은 잘 모르겠네요...
 TFR을 설명하다가 얘기가 잠시 딴 곳으로 새버렸군요. 다시 본론으로 돌아와서, TFR이 28bit와 48bit 두 종류로 이루어져있지만 주소를 지정하는 부분을 제외하고는 실제 command code와 sub-command를 처리하기 위한 feature code의 사용은 거의 동일하기에, 두 경우에 대해 공통적으로 적용되는 각각의 녀석들에 대해 알아보도록 하겠습니다. TFR은 Host to Device(이하 H2D)로의 방향과 Device to Host(D2H)로의 방향에 따라 각각의 녀석들이 다른 의미로 사용됩니다. 일단은 H2D 방향에서 어떻게 사용되고 그 의미가 무엇인지에 대해 알아보겠습니다. 위의 그림들은 모두 H2D 방향입니다. H2D 방향에서 가장 중요한 녀석은 command register 입니다. Command는 host가 device로 어떤 command를 보낼 것인가에 대한 정보를 담고 있습니다. ATA spec.에 나와있는 command는 많이 있으나 그 종류는 딱 세 가지 밖에 없습니다. 더 크게 나누자면 두 종류입니다. data I/O가 있는 command와 없는 command로 일단 나뉘고, I/O의 방향에 따라 DATA in/out으로 나뉘게 됩니다. 여기서 in/out의 방향을 제대로 이해하셔야 합니다. 기준은 host를 말하기 때문에 in이라는 것은 host로 data가 들어오는 것을 의미합니다. Host로 data가 들어온다 즉, 저장 장치로부터 data를 읽으면 그 data가 들어오기 때문에 붙여진 이름입니다. Read 계열의 command가 data in command 입니다. Out은 반대로 write 계열입니다. 물론 모든 command에 대해 read/write로 분류할 수는 없지만 여기서는 in/out의 개념을 설명하고자 한 것입니다. 요약하자면 command register는 어떤 command를 보낼지에 대한 값이고 그 값은 spec.에 정해져 있고, 그 종류는 DATA IN, DATA OUT 그리고 NON-DATA command로 분류할 수 있다입니다.
 Feature register는 위에서 살짝 언급했지만 sub-command를 사용하고 싶을 때 사용합니다. Read나 Write command의 경우 단순하게 data I/O 밖에 없는 경우는 feature register를 사용하지 않습니다. 반대로 ATA command 중에 SET FEATURE라는 녀석이 있는데 이 녀석은 HDD의 여러가지 feature들을 사용자 입맛에 맞게 제어할 수 있도록 해줍니다. 그런데 feature들이 워낙 많으니 각각의 feature들을 제어하기 위하여 각각에 대하여 sub-command code를 할당해놓았습니다. 그래서 host가 command를 실어 보낼 때 특정 feature를 선택하고 싶을 때 각 feature에 해당하는 값을 feature register에 함께 싫어서 보내게 되면, 저장 장치는 이 것에 맞게 해당 feature를 제어하는 것입니다.
 Device register는 말 그대로입니다.
오래전에는 주소 지정 방식이 HDD에서 사용하는 cylinder, head, sector(이하 CHS)와 같은 physical address를 직접 지정해서 access할 수 있는 방식을 사용하던 때가 있었다고 합니다. 그러다 CHS 방식이 위에서 언급한 용량의 한계와 비슷한 문제에 부딛혀서 이를 극복하고자 Logical Block Address(이하 LBA) 방식이 도입되게 됩니다. 이렇다 보니 CHS command와 LBA command를 구분하기 위한 방법이 필요했고 이를 위하여 device register에 bit 하나를 할당해줍니다. 또 예전의 PATA interface 시절에 여러개의 HDD를 사용하고 싶을 때 각각을 구분하기 위해 master/slave라는 개념을 사용했었습니다. 이를 구분하기 위해 또 bit를 할당해주었습니다. 이 외에 feature register 처럼 각각의 command에서 제어하고자 하는 기능들이 다르기 때문에 각 command마다 각자 입맛에 맞게 이를 사용하기도 합니다. 각각의 bit definition은 아래와 같습니다.

 다음은 sector count register입니다. 이름에서 벌써 팍 꽂히지 않습니까? 맞습니다. DATA I/O 계열의 command에서는 얼마나 I/O를 할 것인지에 대한 정보를 담고 있는 녀석입니다. 28bit command에서는 8bits를 사용하기에 최대 I/O size는 255 sectors가 되고, 48bit command는 16bits를 사용하기에 65535 sectors가 최대가 됩니다. 48bit command의 경우 I/O size가 크니 28bit command에 비해 command를 더 적게 사용해도 되는 장점이 있습니다. 하지만 제가 아는바로는 XP는 127 sectors 이상을 사용하지 않습니다. 공전절후의 hit를 기록한 OS XP도 시간이 지나니 점점 퇴물이 되는 것은 어쩔 수 없나 봅니다. NON-DATA command 계열에서는 또 다르게 사용되기도 합니다. Feature/Device register처럼 해당 command에 대하여 sub-control이 필요할 때 사용하기도 합니다. Sub-control/command에 관련된 내용은 각각의 command를 살펴볼 때 어떤 의미와 어떻게 사용되는지 알아보도록 하겠고, 여기서는 간단하게 넘기도록 하겠습니다.
 자 마지막으로 주소 지정 register들입니다. 이 녀석들은 정말 딱 한 개를 제외하고는 NON-DATA command에서는 거의 의미가 없는 녀석들입니다. 좀더 진실을 말하자면 ATA spec.에 있는 command에 대해서지만요. 그리고 위의 그 한 개라는 주인공은 SMART command인데 이 녀석의 복잡도는 ATA command 중 최강을 달리기 때문에 나중에 설명하도록 하겠습니다. 아무튼 주소 지정 register는 DATA IN/OUT command에서 저장 장치의 특정 위치를 access하고자 할 때 그 주소를 지정해주는데 사용합니다. 28bit command는 8bits로 이루어진 register 3개, LBA Low, LBA Mid, LBA High와 device register의 하위 4bit를 빌려서 주소를 지정하게 됩니다. 위의 READ DMA command에 대한 TFR 그림을 보시면 어떻게 구성되는지를 보여줍니다. 48bit는 16bits로 이루어진 LBA L/M/H를 사용하고 따로 빌려쓰지는 않습니다. 그런데 한 가지 좀 복잡한 것이 있다면 순차적으로 L/M/H를 붙이면 LBA가 나오는 것이 아니라 좀 뒤 엉켜 있는 것을 알 수 있습니다. 그 이유는 기존의 28bit 시절에 TFR 뒤에 48bit를 위한 TFR을 추가한 꼴이 되버렸기 때문입니다. TFR은 순차적으로 위치해있는데 그 순서를 뒤바꾸면 호환성에 문제가 생기니 뒤에 추가하게 된 것이고, 그렇다 보니 이렇게 엉망이 되버린 것입니다. 그러나 위의 LBA 계산은 모두 I/O controller chip이 알아서 해주니, 직접 register들을 열어보지 않는 이상 계산상의 수고스러움은 없을 것입니다. 전 직접 열어볼 일이 많기 때문에 애시당초 잘 만들지라는 생각을 매번 하게 되고, 계산할 때마다 짜증이 묻어납니다...
 마지막으로 Device Control register 입니다. Bit 중에 bit 7은 HOB(High Order Byte)로 H2D로는 48 bit/28 bit command에 대한 정보를 알려주는 기능과, bit 2의 SRST는 soft reset에 대한 처리를 위한 기능 그리고 data 전송 제어를 위한 위한 bit 1, nIEN bit 세 가지가 중요하게 쓰입니다. 첫 번째를 빼고는 다소 어렵고 복잡한 내용입니다. 간단하게 얘기를 하자면 RESET coomand를 보낼 때 SRST bit을 set 해서 command를 보내고, nIEN은 device로부터의 INTRQ를 enable하느냐 disable하느냐를 제어하기 위한 bit 입니다. 이건 간단하게 얘기해도 복잡하네요... 써놓고 보니 HOB와 SRST는 이해가 되는군요. nIEN은 아직은 4차원인 것 같으니 차후 SATA protocol을 다룰 때 설명하도록 하겠습니다.
 자, 이제까지 H2D로의 TFR의 의미와 어떻게 쓰이는지 알아봤으니 D2H에 대한 것도 알아보겠습니다.
 D2H로의 TFR은 굉장히 간단하면서도 알아야 할 것들이 좀 있습니다. 간단한 것만 여기서 다루고 알아야 할 것들은 각각의 command를 다루는 부분에서 설명하도록 하겠습니다. 그럼 간단한 것에 대해 알아보죠. 왜 간단하다는 표현을 썼냐면, 기본 적인 틀은 모든 command가 비슷하기 때문입니다. command를 보내는 것이 H2D니 거기에 대한 응답이 D2H가 되고, 이 때 담을 내용은 command를 수행했는데 결과가 어떻더라는 것이 전부입니다. 더 간단하게 말하면 error가 있었냐 없었냐만 알려주면 되는 것이죠. 그래서 D2H TFR set은 항상 status와 error register 값을 유심히 살펴볼 필요가 있습니다.
 먼저 status register는 error가 있었냐 없었냐에 대한 정보와 현재 장치의 상태가 어떠한가에 대한 정보를 담아서 보내주는 녀석입니다. 각각의 bit definition은 아래 그림과 같습니다.

[Status Register의 bit definition]
 그럼 각각의 bit에 대한 의미를 살펴보겠습니다. BSY bit은 현재 장치가 동작 중이라는 뜻으로 busy의 약자입니다. 장치가 해당 command를 수행하기 위해 열심히 뭔가를  하고 있다는 것을 뜻합니다. DRDY는 drive ready의 약자로 말 그대로 새로운 command를 수행할 준비가 되어 있다는 뜻입니다. DF/SE는 각각 device fault/stream error를 뜻하는 것으로, 모든 command에서 set 해서 내보내지는 않습니다. 약 3년 간 HDD를 지켜보고 있지만 단 한 번도 보지 못한 bit 입니다. 잘 안쓰이는 것 같더군요. SE는 streaming command만 set 하는 bit입니다. 이 녀석에 대한 것은 feature set을 다룰 때 살펴보도록 하겠습니다. Bit 4는 저장장치의 종류에 따라 다르게 쓰입니다. 가령 HDD의 경우 seek라는 동작을 매 read/write 마다 수행하기에 일반적으로 DRDY에 bit 4를 함께 set 합니다. 보통 DSC로 불리며무슨 의미냐면, Device Seek Complete를 뜻합니다. 이상 상위 bit 4개에 대해 살펴보았습니다. 한 숨 돌리고 하위 4bit를 살펴보겠습니다. 하악하악(^.^;;;)
 하위 4bit 중 bit 1, 2는 현재 제가 이 글을 쓰고 있는 ATA-7 기준으로는 사용되지 않습니다. 설명할게 줄어서 정말 기쁩니다~. 이번엔 순서를 바꿔서 bit 0부터 설명하겠습니다. 사실 bit 0는 command에 대한 응답으로써의 TFR 중 error가 있었냐 없었냐를 알려주는 매우 중요한 bit입니다. 명칭은 ERR/CHK 이고 Error/Check 입니다. 즉 error가 났으니 error register를 check 해보라 라는 뜻입니다. Bit 3인 DRQ는 Data ReQuest를 뜻합니다. 이것도 각각의 data 전송 방식에 따라 set 되는 위치가 바뀌기는 하지만 기본적인 의미는 data 전송 중이라는 의미입니다. 자 그럼 이렇게도 생각을 해볼까요? Device가 data를 전송 중이라면 바쁜 상황일까요? 아닐까요? 네 당연 바쁜 상황이겠죠. 그래서 보통 DRQ는 BSY bit랑 거의 대부분 함께 짝을 이룹니다. 각각의 protocol 아주 미묘한 시간차에 의해 아닐 때가 있긴 하지만 우리는 인간이니깐 ns(nano second) 차원은 무시해버립시다. 가끔 이런 ns 차원도 다뤄야하기 때문에 interface debugging은 어려울 때가 있습니다. 이상으로 status register의 bit definition을 살펴보았습니다. 이 녀석은 모든 command에 대해 그 응답이 어떠한 가를 나타내는 정보를 담고 있기 때문에 항상 살펴보아야 하고 값에 대해 관심을 가져야 하는 아주 중요한 녀석입니다. 위에서 H2D로의 TFR을 설명하면서 Device Control register를 설명했었습니다. 이게 H2D에서는 Device Control register지만 D2H에서는 Alternate Status register로 사용됩니다. 말 그대로 status register의 복사판이 되겠습니다.
 후아~ 드디어 마지막인 error register 군요. Error register는 각 command가 가지는 동작 특성이 다르기 때문에 각 command에 대해서 bit definition을 다르게 사용합니다. 모든 command에 대해 동일하게 사용하는 녀석이 있긴 합니다. 아래 그림을 보시죠.

  그렇습니다. Bit 2는 ABRT, 즉 abort로써 어떤 command를 보냈을 때 저장 장치가 지원하지 않거나, 조건이 만족하지 않았을 때 거부할 때 쓰이는 bit입니다. 참 건방진 녀석이죠. 전지전능하신 host님께서 command를 보냈는데 일개 주변 장치 따위인 device가 거부하다니요. 아주 간단하게 이런 경우를 가지고 설명을 할 수가 있겠습니다. Packet device와 non-packet device는 각각이 지원하는 command가 다릅니다. Host가 Packet device에 날려야 할 command를 non-packet device에 날린다면, 당연 수행할 수가 없겠죠? 이렇게 각각의 저장 장치에서 지원하지 않는 command가 들어올 때 과감히 abort error를 내는 것입니다. 그럼 이런 경우만 있느냐? 그러면 정말 ATA spec. 쉬워졌을 것입니다. 아쉽게도 state transition을 가지는 command들은 모두 해당 조건을 만족하지 않은 경우에 과감하게 거부해버립니다. State transition을 가지는 feature set과 command의 종류는 다음에 자세히 다루도록 하겠습니다. 더불어 각각의 error bit은 command마다 다르니 command를 다룰 때 이 녀석들을 설명드리도록 하겠습니다. 아... 이건 제가 귀찮아서 그러는 것이 아니라, spec.에서 command에 대해 설명할 때 일반적인 input으로써의 TFR set과 output으로써의 TFR set, 그리고 error가 발생했을 때의 output으로써의 TFR set을 다루기 때문입니다. 무엇보다 너무 글을 길게 썼더니 슬슬 지쳐가기 시작하네요...
 후아.. 이렇게 길게 글을 써본 적이 과연 몇번이나 되는지 모르겠군요. 제가 생각하는 ATA spec.을 이해하는데 있어서 가장 기본이 되는 TFR set에 대한 내용과 이들이 어떻게 사용되는지에 대한 주제로 일반인이 보기에 쉽게 이해할 수 있도록 글을 쓰고자 노력하였습니다. 어떻게 좀 이해가 되시나요? 이 다음글에서는 ATA spec.에서 각각의 특징별로 구분해 놓은 것이 있는데 이를 feature set이라고 하고 이에 대해서 다루고자 합니다.

뒷 이야기,
 1. Mb/s와 MB/s의 차이를 아시나요? MB/s = (Mb/s)/8 입니다. 위의 1.5Gb/s는 overhead를 제외한 순수 전송 속도를 계산하면 192MB/s 입니다.
 2. 예전에 PATA와 SATA 중 뭐가 더 좋은가라는 질문을 받은 적이 있는데, 비교 불가입니다. 무조건 SATA입니다. 전송 속도 차이도 있지만, PATA를 사용하는 저장장치와 SATA를 사용하는 것의 세대 차이는 기술적 의미로 거의 3세대 이상 차이가 나기 때문입니다.
 3. ATA 이야기가 끝나면 SATA 이야기란 내용으로 글을 이어 갈까 합니다.




from http://sutdaeng.egloos.com/2831491

Sutdaeng

댓글 없음:

댓글 쓰기