[App 개발] OS X 를 지원하지 않는 기종을 위한 커널 해킹 (2)
본문
수정된 코드를 PatchedAppleNVRAM 으로 컴파일하는 것은 어렵지 않았습니다. AppleNVRAM 클래스는 짧고 간결했기 때문에, 코드를 복사한 다음 수정해야 할 두 줄만 고쳐 주었습니다. 이제 어떻게 커널이 내 드라이버를 선택하게 할까요?
커널은 사용 가능한 드라이버의 정보를 수집하는 과정에서 드라이버를 선택합니다 (정보는 커널 혹은 커널 익스텐션 내에 들어있습니다). 커널 익스텐션에서 이 정보는 "Info.plist" 파일에 이 정보가 담겨있습니다. 커널 내에 포함된 드라이버의 경우는 커널 소스코드에 정보가 숨어있거나 ioreg 명령을 수행할 때 확인할 수 있는 정보로부터 유추합니다. AppleNVRAM 의 경우 중요 정보는 IOClass, IOProviderClass, 그리고 IONameMatch 에서 볼 수 있습니다.
커널이 드라이버를 선택할 때 "수동적" 인 컴포넌트와 "능동적" 인 컴포넌트가 있습니다. 수동적인 컴포넌트는 커널이 어떤 장치에 대응하는 객체 클래스를 참조합니다. NVRAM 에 대응하는 클래스는 AppleGrandCentralDevice 클래스입니다. 이것은 AppleGrandCentral 드라이버가 발행하는 "nub" 클래스입니다. 드라이버는 그 장치에 특별히 필요한 기능을 첨가하여 (주로 AppleMacIODevice 로부터) nub 서브클래스를 발행합니다. 드라이버의 IOProviderClass 는 필요한 드라이버를 붙여주는 nub 로서, 커널은 특정 클래스 혹은 서브클래스의 nub 에만 대응하게 됩니다. 이후 커널은 연결된 nub 에 따라서 다양한 매칭을 수행합니다. AppleNVRAM 드라이버에는 IONameMatch 가 있어서 "nvram" 라는 이름이 있는 프로퍼티와 대응합니다. 이것이 커널이 AppleNVRAM 클래스를 nvram 장비 드라이버로 연결하는 과정입니다.
커널이 모든 장비에 필요한 드라이버를 검색하고 나면 연결 과정은 "능동적" 상태로 들어갑니다. 커널은 사용 가능한 모든 드라이버에 있는 "probe" 메쏘드를 차례로 호출하여 연결할 장치의 참조 주소를 전달합니다. 드라이버는 전달된 장치가 정말로 자신이 사용할 수 있는 장비인지를 조사하기 시작합니다. 이 때 드라이버는 "probe score" 를 변경합니다. 만약 다수의 드라이버가 어떤 한 장비를 연결할 수 있다고 한다면, 커널은 probe score 가 가장 높은 드라이버를 선택합니다.
따라서 커널이 AppleNVRAM 대신 PatchedAppleNVRAM 을 선택하도록 하는 것은 어려운 일이 아닙니다. 다음과 같이 Info.plist 에서 필요한 부분만 수정해 주면 됩니다:
IOKitPersonalities
PatchedAppleNVRAM
CFBundleIdentifier
oldworld.support.PatchedAppleNVRAM
IOClass
PatchedAppleNVRAM
IONameMatch
nvram
IOProbeScore
200
IOProviderClass
AppleMacIODevice
Listing 3. Partial contents of Info.plist for PatchedAppleNVRAM.kext
IOProveScore 프로퍼티를 보십시오. 만약 단지 probe score 만 변경하는 경우에는 드라이버에 메쏘드를 새로 만들어줄 필요 없이 Info.plist 만 변경해 주면 됩니다. 따라서 위의 Info.plist 의 내용을 보시면, 커널 내의 AppleNVRAM 의 probe score 보다 IOProbeScore 값이 더 크기 때문에, 커널은 내 드라이버를 nvram 장치와 연결해 줄 것입니다.
그 외에도 Info.plist 에 변경해 주어야 핲 프로퍼티가 있는데, OSBundleRequired 프로퍼티는 반드시 "Root" 로 해 주어야 합니다. 왜냐하면 드라이버 연결 과정은 Mac OS X 부팅시 두 단계로 이루어지기 때문입니다. 먼저, BootX 라고 불리우는 부트로더는 부팅 과정 초기에 필요한 커널 및 커널 익스텐션을 읽어들입니다. 그 다음 BootX 는 커널을 실행시키고, 커널은 루트 장치를 마운트하기 위한 드라이버 연결 과정을 시작합니다. 그 다음은 루트 장치에 기록된 시동 스크립트에 의거하여 작업을 속행합니다. 이 과정에서 나머지 장치와 드라이버를 연결하는 두 번째 과정이 수행됩니다. OSBundleRequired 프로퍼티는 PatchedAppleNVRAM 커널 익스텐션이 첫 번째 드라이버 연결 과정에서 필요한 것인지를 BootX 에 알려주는 역할을 합니다. 만약 이 드라이버가 첫 번째 과정에서 연결되지 않으면 내장된 AppleNVRAM 이 연결되어 버리고 말 것입니다.
보시면 상당히 쉽지요. 실은 이것이 모든 Mac OS X 드라이버 시스템의 기본 과정입니다. 그 외에 어떤 어려운 작업이 필요가 없지요. 게다가 애플은 AppleNVRAM 내에 어떤 특이한 과정을 넣거나 하는 그런 일을 하지 않았습니다. 그저 AppleNVRAM 드라이버를 IOKit 드라이버 시스템의 표준에 따라서 코딩해 주었을 뿐입니다. 따라서 표준에 의거하여 프로그램을 넣기만 하면 커널 내의 원래 코드를 우회하는 커널 익스텐션을 만들어줄 수 있습니다.
... 다음에 계속 ...
최신글이 없습니다.
최신글이 없습니다.
댓글목록 0