가장 많이 본 글

2014년 10월 6일 월요일

리눅스 커널 심층 분석 - 17장, 장치와 모듈

리눅스는 모놀리틱 커널로서 모듈 독립적이지 않고 수정하면 전체를 build 해야 하는 system이다.

다음은 insmod / rmmod 하는 과정이다.
이미지
pic1
insmod / rmmod는 user app인데실행시에는 ko user 영역에 copy kernel 영역에넣는다.
mknod: 장치 driver 접근하기 위해서 VFS node 
--> /dev/SK dentry 찾아서 inode 만든다. 때는 file 만들어지지 않았기 때문에 &def_cur_fops 가리키고 있다. open() 하면, files 비어있는 fd[3] 객체를 만들면서 f_dentry, f_op 등을 매핑한다. 그런 후에 device reg 넣은 &SK_fops 불러다가 open 하게 !! 이후에는 직접 SK_open()으로 간다! 
/proc/devices에서 정보를 확인할 수 있다.
device module이란?
--> device들을 character device로 등록하자니.. 많아지니깐 관리가 힘들어짐.
--> 그래서 VFS(Virtual File System)가 만들어짐. charicter device / block device / network device를 접근할 수 있음.
--> 장치 유형은 다음과 같다.
  • Blkdevs, 블록 장치 - HDD 
  • Cdevs, 캐릭터 장치 - 키보드, 마우스 
  • Network  devices, 네트워크 장치 - 이더넷 장치 

이미지

 
hello world device driver:

static int hello_init(void) 
{ 
pr_info("Hello world!"); 
return 0; 
} 
 
static void hello_exit(void) 
{ 
pr_info("Goodbye world!"); 
} 
 
module_init(hello_init); //시작지점 hello_init 등록 
module_exit(hello_exit); //모듈이 메모리에서 제거될 때 호출 
 
MODULE_LICENSE("GPL"); 
MODULE_AUTHOR("author"); 
MODULE_DESCRIPTION("Hello world, module"); 
모듈 만들기 - Makefile 추가 
모듈 설치 
  • 위치: /lib/module/버전/kerne/drivers/xxxx/helloworld.ko 
  • # make modules_install //설치 
모듈 의존성 생성 
  • # depmod -A 
  • /lib/module/버전/modules.dep //모듈 의존성 정보 
모듈 적재 
  • # insmod helloworld.ko //모듈을 메모리에 추가 
  • # rmmod helloworld //삭제 
  • # modprobe helloworld [모듈인자] //해당 모듈이 필요로 하는 다른 모듈도 설치 
  • # modprobe -r helloworld //삭제 
설정 옵션 관리 - Kconfig 
모듈 인자 
  • module_param(name, type, perm); //이름, , 권한 
  • module_param_named(name, variable, type, perm); //외부 노출 이름, 내부 변수, , 권한 
  • module_param_string(name, string, len, perm); //이름, 내부 변수(string 문자열임), , 권한 
  • module_param_array(name, type, nump, perm); //이름, , 배열에 저장할 항목 개수, 권한 
  • moduel_param_array_named(name, array, type, nump, perm); 
  • MODULE_PARM_DESC(): 설명 추가 
  • <linux/module.h> 함수에 대한 설명 있음 
노출 심볼 
  • EXPORT_SYMBOL() 
  • EXPORT_SYMBOL_GPL() //EXPORT_LICENSE("GPL")  
  • 장치 모델 
  • <linux/kobject.h> kobjects(kernel object type) 
  • <linux/kobject.h> struct kobject 
  • <linux/cdev.h> struct cdev struct kobject 들어가면 kobject 제공하는 표준 함수를 있음. 
  • Struct ktype: kobject 기본 속성을 정의함. 소멸 동작, sysfs 동작 기본 동작, 쉽게는 공유 동작의 집합임. 
  • Struct kset: 
  • 묶여있는 kobject 묶음의 기본 클래스로 동작함 
  • 연관이 있는 kobject 모아줌 
  • Struct kobject * kobject_create(void); 
  • struct kobject *kobj; 
  • kobj = kobject_create(); 
  • if (!kobj) 
  • return -ENOMEM; 
    • 참조 횟수 증감 
    • struct kobject *kobject_get(struct kobject *kobj); 
    • void kobject_put(struct kobject *kobj); 
    • 확인은 kref_get() 사용 
    • Sysfs 추가/제거 
    • int kobject_add(struct kobject *kobj, struct kobject *parent, const char *fmt, ...); //추가 
    • void kobject_del(struct kobject *kobj); //제거 
    •  
    • /proc 파일 만드는 -insmod하면 /proc 파일을 하나 만드는거다! 
    • create_proc_entry() / remove_proc_entry() 이용하면 . 
    • 예제 /06.FileSystem/03.proc_my 확인할  
    • /sys (참고) 
    • 2.6 이전에는 /sys (systfs) 없었음. 디바이스 모델과 함께 추가된 것이라고 생각하면 . 
    • /sys 그렇지 않지만 /proc 맘대로 만들어도 된다. 
    • /sys/class 논리적인 장치 
    • /sys/bus device들이 붙어있음.
    •  
    • module_init() 주소 보다 module_exit() 낮은 주소값을 가지고 있다. 
      • 웃긴건 /proc/modules 나오는 주소가 module_exit() 동일한 주소를 가지고 있다. module_exit 함수들 처음이고 모듈의 주소랑 동일하다고 보면 된다. 
    • kernel 시작 주소는 #define TASK_SIZE 0xBF000000 설정 가능함. 
    • application open() 호출하면, 
      1. 'swi5' system call 하여 kernel mode(svc) 변경됨. sys_open() 호출함. 
      2. sys_open() inode file_operations i_rdev에서 major/minor 정보를 확인함 
      3. struct file 생성한 위에 로드한 file_operations 멤버에 load. 
      4. .open = mydrv_open() 호출함. 
      5. 앱의 fd = open() open() mydrv_open() return 아닌 sys_open() return 값임. file pointer 값임. 
    • read() 호출하면 
      1. 바로 file_operations 접근할 있음. 
    • close() 호출하면 
      1. 'swi6' system call 하여 kernel mode(svc) 변경 
      2. sys_close() 호출 
      3. mydrv_close() 호출 
      4. file_operations 삭제 
    • LDM 대해서… 
      1. 목적: PnP/Power 통합관리 
      2. 내부 구조: 객체(kobj), sysfs  node 생성. 
      3. 구현 방법: (TBC) 
      4. 모든 드라이버에는 kobj 등록해야 한다. 
      5. 윈도우의 WDM 따라했음 
    • 장치파일/디바이스 네임/모듈 네임 
      • 장치파일: mknod 명령으로 생성, 응용프로그램이 사용 
      • 디바이스 네임: 
        • # cat /proc/devices 실행시 출력 
        • 드라이버소스에서 설정하여 커널에 등록 
      • 모듈네임: 
        • lsmod 실행시 출력 
        • 드라이버 소스 빌드시 결정 
    • /dev 폴더에 대해서.. 
    • Android 부팅 전에는 /dev 없다. init process 하면서 device 들을 확인하여 하나씩 넣는다. 
    • desktop kernel 부팅시 /dev 만들어짐. package에서 동적으로 만들어줌. 

댓글 없음: