아직 사무실에 있지만... 왠지 오늘은 글이 쓰고 싶다. 사무실에 홀로 앉아 머리 식히며 요즘 하고 있는 재미 있는 기술을 간단히 정리해 보고자 한다. 누군가 운이 좋다면 내가 한 일을 다시 할때 아주 조금은 도움이 되기를 바란다.
요즘, 회사에서 하는일은 PCI express를 이용해서 실 세계의 data를 빨리 system memory로 이동하는 기술을 구현하고 있다.
흔히 PCI-e는 PC 주변 기기들로는 알고 있어도 개발에 직접 활용하기에는 아직 그렇게 일반적이지는 않을것이라고 생각한다.
지금 진행하는 project는 PCI-e x8 (lane이 8개) 를 이용하여 최대 2Gbits/sec 의 속도로 data를 들여온다. (무진장 빠르기는 하지만.. 정밀하게 계산해 보면 차떼고 포떼고.. 현재 PC chip-set의 제약등으로 양방향 최대 약 200MBytes/sec정도의 bandwidth를 가짐.)
사용하는 OS는 Windows XP 64 bit이며, DMA를 이용하며 data를 전송한다. 지금 나의 주 업무는 device driver의 개발이다. MS에서 KMDF라는 driver framework을 제공하며 비교적 최근의 기술이다. 덕분에 몇년만에 다시 device driver를 시작했다. 예전에는 driver works(driver studio였나?? numega꺼 였었던것 같은데..)같은 3rd party framework을 사용했는데.. 지금은 왜 그런 업체들이 다 죽었는지 알만할 정도록 driver개발 환경이 너무 좋아졌다.
아무튼, DMA는 common buffer를 이용한 scatter-gather라는 기술을 이용하며, 이번 project에서는 MS의 driver쪽 전문가의 조언을 받아 전혀 새로운 기능 (거창하게 들릴지도 모르겠지만.. 쩝.. sample code에는 없기에ㅋ)을 구현해서 이용하고 있다. 다행이 미국쪽에서 호응이 좋다.
요즘, 진행하고 있는 일은 hot-plug기술이다. 이게 뭐냐면.. 단순하게 USB처럼 PC가 동작중에 임의로 장치를 연결/제거할 수 있는 것이다.
하지만, PCI-e도 USB처럼 쉬울것 같은가? 나도 처음에 PCI-e spec을 들여다 본 후 쉬울 줄 알았다. 하지만, 세상은 언제나 처럼 그렇게 만만하지 않았다.
가격 문제로 target product의 mothor board는 상용의 제품을 쓰기로 결정을 했다. 그리고, CPU는 현재 인기 좋은 Intel i7이고 chip-set은 x58을 이용한다. 그리고, 결정적으로 OS는 XP 64bit다.
이 조합은 Hot-plug기능을 하는데.. 제약이 너무 많다. 일단, 일반 상용 mother-board는 PCI-e에 대하여 hot-plug를 전혀 고려해 두고 개발되지 않았다. 예를 들어 ACPI를 들여다보면 관련 기능이 전혀 없다. X58 (IOH10)의 설정을 debugger로 들여다 봐도 관련하여 hot-plug기능을 전혀 활성화 시켜놓지 않았다. 설령 ACPI에서 해당 기능을 지원한다고 해도 OS가 ACPI spec 1.0b에 _HPP method만 (ACPI 2.0에 있는 기능) 지원하고 MSI도 지원하지 않아 제약이 너무 많다.
결국, ACPI를 수정해서 overload해야 하고 (현재 사용하는 PLX의 PCI-e switch에 있는 기능을 이용하기 위해서) OS도 최신 VISTA이상을 이용하면 일이 쉽게 가능하다. 사실, Windows XP가 해당 기능을 지원하지 않는 것은 아니다. 하지만 현재의 구성으로 제약이 너무 심한 것이 사실이다. 예를 들어 IOH10에서 GPE[1]이 hot-plug event이기는 하지만.. 이 event를 만들어 내기가 쉽지 않다.
ACPI BIOS를 overload하고 (_OSC method제공및 관련 GPE event handler설정), OS를 VISTA나 I7을 쓰더라도.. 이번에는 드라이버의 인증 문제가 남는다. 개발자 인증을 하고 개발자 mode로 하더라도, 자동으로 PCI-e 장치가 re-enumulation되면 분명 드라이버 설치 여부를 물어볼 것 같은데.. (아직 실험해 보지 않았지만.. 그럴 것 같음) 이래서는 완전 자동이 되지 않을 것 같다. 지금 인증을 받기도 벅찬 상황이고..
이번에 약 2주동안 부랴부랴 PCI-e hot-plug공부를 하면서 관련된 자료가 너무 부족하고 패쇄적이라고 느꼈다. 2003년 부터 2009년까지 자료들이 체계없이 인터넷에 (대부분 MS자료)있고, PCI-e 기술자료는 PCI SIG에 가입되어 있지 않은 일반 개발자는 거의 구할 수 없을것이다. 쩝.
한가지 흥미로운 사실은..우리나라 site에서는 ACPI BIOS를 hacking해서 windows 정품 인증 받는 기술 말고는 전혀 찾을 수 없어서 아쉬웠다. 이런 방법이 있는 줄도 처음 알았고.... 물론 외국에서 먼저 시작한 것을 그대로 가져다가 하는 것 이지만.... 나름, 꽤나 ACPI를 잘 이해한 사람들도 볼 수 있었던것 같은데.. 흥미가 있었으나.. 아쉬웠다. 음지의 기술이기도 하고.
혹시나 해서 나처럼 PCI-express를 이용하여 hot plug를 구현해야할 개발자 들은 아래의 참조하면 좋을 것 같다.
- PCI-e hot plug가 지원되는 ACPI BIOS를 가지고 있는지?
- 보통 일반 사용자를 위한 mother board의 edge-slot은 (일반 slot) hot-plug가 되지 않음. 별도의 지원되는 switch board가 있어야 함.
- Windows XP는 ACPI 1.0b + _HPP (ACPI 2.0) 만 지원함. 엉뚱한 MS기술자료 보고 헛갈리지 말것. 즉, ACPI BIOS에 _OSC만들어 넣어도 소용없음.
- 현재 mother boad의 ACPI BIOS는 intel에서 만든 iasl라는 free tool로 빼낼 수 있음.
- MS의 asl이라는 tool로 해당 수정된 ACPI BIOS code를 compile하고 overloading할 수 있음. (BIOS를 다시 굽는 것이 아니라 registry에 넣고 booting시 새로 loading하는 방법으로 안전하고, 언제라도 다시 복구할 수 있음)
- ACPI BIOS가 어떻게 돌아가는지 보거나 debugging하려면, 해당 OS의 checked version이 필요함.
- Windows XP 32bit의 checked version은 현재 MSDN subscription으로 받을 수 있기는 하나.. Media center로 받아야 함. MS에 시정 요청을 하기는 했지만.. 언제 해줄런지는 모름.
- Hot-plug기능 실험할때 전기적인 충격으로 인한 system 손상에 주의. (벌써 system 한대 사망)
- Hot-plug후에 항상 x8로 link되는 것이 아니니 link되었다고 안심하지 말고.. 꼭 확인 바람. (Config space를 통해 확인)
- PCI-express의 확장 configuration space (0x100번지 이상)는 일반적인 !pci 명령으로 볼 수 없음. 이때는 memory mapped configuration space를 이용해야 함. chip set의 특정 register중에 해당 base address를 설정하는 부분을 참고하여 시작 주소를 찾고 계산해야 함. (예를 들어, 지금 사용중인 IOH10-x58-의 경우 bus 0, device 30, function 0의 address 20~23에 있는 configuration register가 그 시작 주소를 지정하고, 일반적으로 system memory상의 0xe0000000에 mapping되어 있음. PCI express 표준에 의하면 확장 memory map addressing은 bit[20..22]가 bus번호, bit[15..19]가 device 번호, bit[12..14]가 function 번호다. 즉, bus0:dev0:fun0를 access할 려면 !dd [c] e0000000 이라고 하면 (WinDbg명령) 된다. 만약 bus0:dev3:fun0라면 !dd [c] e0018000이라고 하면 된다. 32bit 단위로만 access되며 cached access이고 아래 주소 bit[2..11]까지가 register의 32bit 단위 주소가 된다. 예를 들어 bus0:dev3:fun0의 0x188 확장 register에 data를 쓰려면, !ed [c] e0018188 12345678이라고 하면 0x188주소에 0x12345678이라는 값을 쓰게되는 것이다. (일반인이 해당 표준일 구하기 어려워서.. 가능하면 상세하게 기술함..)
- 개발하고자 하는 system에 사용되는 chip set에 (north bridge, sough bridge모두)대하여 충분하게 이해하고나서 ACPI code를 봐야 시간이 적게 걸릴 것이라고 생각함.
- PCI-express 표준에 대하여 익숙해 져야함.. 하지만 PCI-SIG에 가입을 해야하는 관계로.. 쩝. 책을 살 수도 있음.
- x58 IOH10과 같은 비교적 최신 chip-set이라고 해도 PCI-express의 max payload size (한 방에 보낼 수 있는 연속 data의 크기)가 최대 256bytes이며 그나마, 일반적으로는 BIOS에서 128bytes로 설정되어 있음. 즉, PCI-express의 최대 성능을 뽑아서 쓸 수 없음. (root complex를 통해 main memory와 access하는 것을 의미)
이번에 ACPI BIOS와 Hot-plug를 공부하면서.. 그 동안 아무 생각없이 이용만 하던, chip-set과 각종 PC device들에 대하여 속속들이 자세하게 볼 수 있었고.. 굉장히 재미 있었다. 누군가, 표준 PC에 PCI-express나 smart battery, 온도 센서등등을 확장해서 표준처럼 구현하기를 원하지만.. ACPI BIOS를 어떻게 이용할줄 몰라서 고생하는 사람이 이 글을 보고 조금이라도 빠르고 쉬운 방법을 찾기를 희망하며..