리눅스 디바이스 드라이버를 플렛폼 디바이스 규칙에 맞게 작성하면 몇 가지 편리한 점이 있습니다.
그 중 하나가 셸 커맨드로 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)
빨리 문제를 해결해야 겠습니다.
'Core BSP 분석 > 리눅스 커널 핵심 분석' 카테고리의 다른 글
[Linux Kernel] Selinux: selinux_enabled (0) | 2023.05.06 |
---|---|
Asan(Address sanitizer, AddressSanitizer) 이란 (0) | 2023.05.06 |
[리눅스] 프로세스를 지정한 CPU에서 실행: sched_setaffinity() 함수 (0) | 2023.05.06 |
[리눅스커널] CONFIG_FUNCTION_TRACER를 키는 방법 (0) | 2023.05.06 |
[리눅스] LK(Little Kernel): 전처리 파일을 위한 설정(--save-temps) (0) | 2023.05.06 |