반응형
이전 2.6 커널기준 이며, 최신커널에서는 해당내용들에 해당하지 않습니다.
Linux Device Module
Linux Device Driver를 작성하다보면 드라이버를 모듈로 작성하여 관리할 때가 있다. 혹은 초기 작성 및 테스트 시 모듈로 컴파일하여 Test를 진행해야 할 때도 있을 것이다.
Linux의 버전이 2.6.xx대로 접어들면서 생긴 가장 큰 변화중의 하나가 platform device driver라는 개념이다.
임베디드 환경에서 대부분의 경우 platform device는 정적으로 할당되어 커널의 시작과함께 계속적으로 메모리내에 상주하다가 단말기의 전원 차단과 함께 종료된다. 하지만 usb / i2c-client 등의 device driver는 그 용도에 따라 모듈로 작성되어 동적으로 커널에 적재/해제를 해야하는 경우가 발생한다. 이러한 디바이스들에도 platform device driver모델이 적용될 경우가 있으며 이러한 경우에는 platform device는 이전에 언급한 것처럼 정적으로 할당한 경우 platform_device_unregister()
룰 이용하여 해제를 하려하면 커널 에러가 발생한다.. (다행히 패닉으로 커널이 뻗어버리지는 않더라는... )
따라서 이때 사용하는 함수들에 대해서 살펴보자..
platform device와 platform_drier의 선언 및 등록
platform device와 platform_drier의 선언 및 등록은 다음과 같이 한다.
/* declare platform driver */
static struct platform_driver XXX_driver = {
.drive = {
.name = "xxx", .owner = THIS_MODULE,
}, .probe = xxx_probe, .remove = xxx_remove,
};
/* declare platform device */
static struct platform_device * xxx_device; /* 플랫폼 디바이스의 동적 할당 */
static int __init xxx_init(void)
{
int res = 0; res = platform_driver_register(&xxx_driver); if(res) {
dprintk("platform driver register fail\\n"); return res;
}
xxx_device = platform_device_alloc("xxx", id_number); if(!xxx_devie) {
dprintk("platform_device_alloc() fail\\n"); return -ENOMEM;
} res = platform_device_add(xxx_device); if(res) {
dprintk("platform_device_add() fail\\n"); platform_device_put(xxx_device); platform_device_unregister(&xxx_driver); return res;
} return 0;
}
static void __exit xxx_exit(void)
{
platform_device_unregister(xxx_device); platform_driver_unregister(xxx_driver);
}
module_init(xxx_init);
module_exit(xxx_exit);
platform_device_unregister()
는 내부적으로 platform_device_put()을 호출하고 결국에는 메모리를 해제하려 든다..- 따라서 struct platform_device를 정적으로 컴파일하고 모듈 적재/해제를 하면 이와 관련된 에러가 커널로부터 출력되는 것을 볼 수 있다.
- 이를 해결하는 방법은 위에서 적은 순서대로 struct platform_device를 동적으로 할당하여 관리하고 해제하는 것이다.
반응형