로드 가능한 커널 모듈 (Loadable Kernel Module)
- 커널 이미지에 포함X -> 부팅시간, 메모리 절약
- 커널에 덧 붙여서 커널의 기능 확장
- 커널 주소 공간에서 실행
- linux/drivers/ 로 이동
- comento dir생성
- linux/drivers/comento에서 Kconfig, Makefile 생성
<linux/drivers/comento/Kconfig> 설정
menu "Comento Example Driver" # 메뉴 이름 설정
config COMENTO_EXAMPLE
tristate "Comento Example Driver Module" # 3가지 옵션, y m n 사용가능
help
This is an Example
endmenu # 메뉴 그룹 종료
- 드라이버 모듈 설정 옵션을 정의
<linux/drivers/comento/Makefile> 설정
obj-$(CONFIG_COMENTO_EXAMPLE) += comento.o
comento-objs += main.o
- CONFIG_COMENTO_EXAMPLE은 m으로 설정
- obj-m += comento.o로 확장
- comento.o는 모듈로 빌드 -> comento.ko 생성
<linux/drivers/Kconfig> 설정
...
...
source "drivers/comento/Kconfig"
마지막 부분에 추가
- 파일의 내용을 현재 위치에 포함
<linux/drivers/Makefile> 설정
...
...
obj-y += comento/
마지막 부분에 추가
- 해당 디렉토리/하위디렉토리를 전부 포함해서 빌드 대상으로 추가
커널에 새로운 모듈 추가
<linux/drivers/comento/main.c> 작성
#include <linux/module.h>
static int __init comento_module_init(void)
{
printk(KERN_DEBUG "module [%s] init \n", __func__);
return 0;
}
static void __exit comento_module_exit(void)
{
printk(KERN_DEBUG "module [%s] exit \n", __func__);
}
module_init(comento_module_init);
module_exit(comento_module_exit);
MODULE_AUTHOR("Jin Minu");
MODULE_DESCRIPTION("Example Drvier");
MODULE_LICENSE("GPL v2");
코드 작성 후,
- 커널 재 빌드
- rootfs를 임시로 mnt디렉토리에 마운트
- 완성된 모듈 .ko 파일을 mnt/usr/lib/modules/ 에 복사
- sync
- umount 실행
- QEMU 실행
- insmod, lsmod, rmmod 로 모듈 로드/언로드
- dmesg로 확인
Kernel API
- 메모리 관련
- 더블 링크드 리스트
- 해시테이블
- 뮤텍스
- 스핀락
1. 메모리 관련
- copy_from_user(to, from, size) : 사용자 공간 -> 커널 공간으로 메모리 복사
- copy_to_user(to from, size) : 커널 공간 -> 사용자 공간 메모리 복사
- kmalloc(size, type) / kzalloc(size, type) : 커널 공간에서 메모리 동적 할당
- type: GFP_KERNEL, GFP_ATOMIC, GFP_DMA
2. Doubly Linked List
- linux/list.h에 정의
- list_head 구조체 사용
API
- LIST_HEAD(name)
- list_add(new, head) / list_add_tail(new, head)
- list_del(target)
- list_empty(head)
- list_for_each_safe(node, temp, head, member_name)
3. Hash Table
API
- DEFINE_HASHTABLE(name)
- hash_add(table, new, key)
- hash_del(target)
- hash_for_each_possible(table, node, member, key)
- hash_for_each(table, bkt, node, hash)
4. Mutex
- 동시에 접근하면 안되는 부분 지정 -> 하나의 변수를 동시에 수정한다면 문제 발생
- 접근해서 작업이 오래걸릴 것을 예상 -> 컨텍스트 스위칭 발생
- 바로바로 작업이 끝나고, 제어권 변경?? -> 스핀락 유리
API
- DEFINE_MUTEX(name)
- mutex_locK(mutex)
- mutex_unlock(mutex)
5. Spinlock
- 뮤텍스와 비슷, But 무한루프 사용해서 상태 바뀔 때까지 대기 -> 컨텍스트 스위칭 안함
- Read-Write lock 형태 많이 사용
- 데이터 read할 땐 여러 프로세스 허용
- 데이터 write할 땐 하나의 프로세스만 허용
- 쓸 때 읽는 것도 허용X
API
- DEFINE_RWLOCK(name)
- read_lock(mutex) / write_lock
- read_unlock(mutex) / write_unlock
6. Current task
- current: 현재 프로세스 참조, 전역변수, 커널 아무대서나 사용
- aarch64에서는 특정 레지스터에 주소 보관
- macro, inline함수
'Linux' 카테고리의 다른 글
| objdump활용 vmlinux 분석시 start address의미 (0) | 2025.09.11 |
|---|---|
| 디바이스 드라이버 (0) | 2025.08.01 |
| ls 명령어 분석 with strace (1) | 2025.07.29 |
| Kernel 및 System call 디버그 with GDB (0) | 2025.07.28 |
| 커널 시스템콜 추가 (3) | 2025.07.25 |