본문 바로가기

Core BSP 분석/리눅스 커널 핵심 분석

[리눅스커널] 드라이버: 셸로 bind와 unbind 명령어를 입력해 probe/remove 함수 호출하기

리눅스 디바이스 드라이버를 플렛폼 디바이스 규칙에 맞게 작성하면 몇 가지 편리한 점이 있습니다.
그 중 하나가 셸 커맨드로 probe/release 함수를 호출할 수 있다는 점입니다.
 
모듈 타입 디바이스 드라이버를 검증할 때 활용하면 좋을 꿀팁이니, 많은 개발자 분들이 활용했으면 좋겠습니다.
 
셸 명령어로 디렉터리 확인하기
 
먼저 /sys/bus/platform/drivers/gpio-keys 디렉터리로 이동합시다.
 
pi:/sys/bus/platform/drivers # cd gpio-keys/
pi:/sys/bus/platform/drivers/gpio-keys # ls
bind  soc:gpio_keys  uevent  unbind
 
확인하니 bind와 unbind 파일이 보입니다.
 
pi:/sys/bus/platform/drivers/gpio-keys # ls -l
total 0
--w------- 1 root root 4096 2018-06-11 03:48 bind
lrwxrwxrwx 1 root root    0 2018-06-11 03:48 soc:gpio_keys -> ../../../../devices/soc/soc:gpio_keys
--w------- 1 root root 4096 2018-06-11 03:48 uevent
--w------- 1 root root 4096 2018-06-11 03:48 unbind
 
아래와 같은 셸 커맨드를 입력합시다.
 
pi:/sys/bus/platform/drivers/gpio-keys # echo "soc:gpio_keys" > bind
pi:/sys/bus/platform/drivers/gpio-keys # echo "soc:gpio_keys" > unbind
 
관련 코드 분석
 
여기서 'echo "soc:gpio_keys" > bind' 혹은 'echo "soc:gpio_keys" > unbind' 명령어를 입력하면 어떤 함수가 호출될까요? 각각 gpio_keys_probe()/gpio_keys_remove() 함수가 호출됩니다.
 
다음은 위에서 언급된 함수가 선언된 코드입니다.
 
static struct platform_driver gpio_keys_device_driver = {
.probe = gpio_keys_probe,
.remove = gpio_keys_remove,
.driver = {
.name = "gpio-keys",
.owner = THIS_MODULE,
.pm = &gpio_keys_pm_ops,
.of_match_table = of_match_ptr(gpio_keys_of_match),
}
};
 
커널 크래시 문제 확인
 
그런데 다음과 같은 명령어를 입력했더니,
 
pi:/sys/bus/platform/drivers/gpio-keys # echo "soc:gpio_keys" > bind
pi:/sys/bus/platform/drivers/gpio-keys # echo "soc:gpio_keys" > unbind
pi:/sys/bus/platform/drivers/gpio-keys # echo "soc:gpio_keys" > bind
 
데이터 어보트가 발생하네요.
 
000|do_DataAbort(?)
-001|__dabt_svc(asm)
 -->|exception
-002|sysfs_remove_file_ns(kobj = 0xFFFFFFF7, attr = 0xC19BEA30, ns = 0x0)
-003|switch_dev_unregister(sdev = 0xC19A1964)
-004|gpio_keys_setup_key(inline)
-004|gpio_keys_probe(?)
-005|platform_drv_probe(_dev = 0xEB490A50)
-006|really_probe(inline)
-006|driver_probe_device(drv = 0xC19A191C, dev = 0xEB490A50)
-007|bind_store(drv = 0xC19A191C, ?, count = 14)
-008|drv_attr_store(?, ?, ?, ?)
-009|sysfs_kf_write(?, buf = 0xC19BEA30, ?, pos = 0)
-010|kernfs_fop_write(?, ?, count = 14, ppos = 0xE1E75F80)
-011|vfs_write(file = 0x0, buf = 0x0, ?, pos = 0xE1E75F80)
-012|SYSC_write(inline)
-012|sys_write(?, buf = -1471503740, count = 14)
-013|ret_fast_syscall(asm)
 
빨리 문제를 해결해야 겠습니다.