1.1. 읽기전에
이 문서의 내용은 Linux kernel v2.6 기반을 기준으로만 정리합니다.
(출처: https://wiki.openwrt.org/doc/networking/praxis)
[PNG image (992.73 KB)]
1.2. 용어정의
문서를 간결하게 표시하기 위해서 다음과 같이 용어를 사용합니다. 여기서 표시되는 용어는 일반적인 표기로 사용되는 약식표현이 아닐수도 있습니다.
NDD: Network device driver
NDD: Network device driver
1.3. Driver개발에 필요한 기초사항
Module의 진입점은 module_init(함수명)으로 소스에 명시합니다. 모듈의 제거점은 module_exit(함수명)으로 소스에 명시합니다. 이때 module_init의 함수는 함수 원형이 "int __init func(void)" 이어야 하며 module_exit의 함수는 함수 원형이 "void __exit func(void)" 이어야 합니다. PCI driver의 경우는 pci_driver구조체를 적절히 채우고 pci_register_driver함수의 인자로 넘겨주어 등록합니다.
1.4. Linux의 Network 구성
Linux에서는 크게 NDD(Network device driver)계층과 Protocol stack부분을 지원하게 되며 이에 수반되어 필요한 Network API system call을 통하여 Application의 Socket과 Data를 교류하게 됩니다. 이 문서에서 다루고자 하는 부분은 Network device와 Protocol stack과 연결하는 부분인 NDD(Network device driver) 입니다.
1.5. NDD의 적재과정 요약
Linux에서는 NDD를 설계 및 구현하는데 서로 상이한 구조로 인한 개발의 어려움을 해소하고자 공통적인 구현부에 대한 일반화 방식을 많이 준비해두었습니다. 그러므로 NDD를 개발하는데 필요한 설계노력을 투자하지 않고 구현에만 집중할수 있게 됩니다. 중요한것은 적어도 이러한 일반화 방식을 이해하려면 가장먼저 NDD의 적재과정을 간략히 살펴볼 필요가 있겠습니다.
- XXX_init_module함수를 통해서 Driver가 초기화를 시작하도록 구현합니다.
- net_device 구조체를 초기화 합니다.
- net_device구조체를 초기화 하는 방법은 크게 2가지로 나뉘는데 전역변수를 사용하는 방법과 할당하여 사용하는 방법이 그것입니다.
- net_device를 할당하는 함수는 alloc_netdev 함수를 사용하거나 좀더 Type별로 세분화된 할당함수를 사용할수 있습니다.
- 이 과정에서 Interface name도 결정할수 있습니다.
- register_netdev함수로 net_device구조체를 등록합니다.
- XXX_cleanup_module함수를 통해서 Driver 제거 과정을 시작하도록 구현합니다.
- unregister_netdev함수로 net_device구조체를 등록해제합니다.
- 만약 net_device구조체가 alloc_netdev 함수계열로 할당된 경우라면 free_netdev로 Memory에서 해제합니다.
1.6. net_device 구조체
"linux/netdevice.h" 헤더파일에서 구조체 원형을 찾을수 있습니다.
1.7. alloc_netdev, free_netdev
alloc_netdev함수의 원형은 다음과 같습니다. (Linux kernel v2.6.27기준)
free_netdev함수의 원형은 다음과 같습니다. (Linux kernel v2.6.27기준)
struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, void (*setup)(struct net_device *), unsigned int queue_count); #define alloc_netdev(sizeof_priv, name, setup) \ alloc_netdev_mq(sizeof_priv, name, setup, 1)
void free_netdev(struct net_device *dev);
1.8. register_netdev, unregister_netdev
register_netdev함수의 원형은 다음과 같습니다. (Linux kernel v2.6.27기준)
unregister_netdev함수의 원형은 다음과 같습니다. (Linux kernel v2.6.27기준)
int register_netdev(struct net_device *dev);
void unregister_netdev(struct net_device *dev);