레이블이 linux인 게시물을 표시합니다. 모든 게시물 표시
레이블이 linux인 게시물을 표시합니다. 모든 게시물 표시

2014년 10월 16일 목요일

man page 작성법..

linux 표준함수, 쉘 바이너리 등 terminal에서 실행하려는 것들에 대한 궁금증이 있으면,
가장 먼저 찾아보는 man page!

man page에 대해 알아보고 작성하는 방법을 정리한다.
man page를 열 때
$ man $(NUMBER) $(TARGET)
NUMBER에 해당하는 숫자는 무엇일까?
섹션 이름
1 누구나 실행할 수 있는 사용자 명령 (User Commands)
2 시스템 호출 (System Calls), 즉 커널에서 제공하는 함수
3 C 라이브러리 함수 (C Library functions)
4 디바이스와 네트워크 인터페이스 (Devices and Network Interfaces), 즉 /dev 디렉토리에 있는 특별한 파일들
5 파일 포맷 (File Formats), 예를 들어 /etc/passwd
6 게임과 데모 (Games and Demos)
7 환경, 테이블, 매크로 (Environments, Tables, and Macros) 등의 잡다한 여러 가지들
8 시스템 관리자만 실행할 수 있는 시스템 관리용 명령들 (Maintenance Commands)
9 커널 루틴에 관련된 문서들의 리눅스만의 독자적인 저장소
n 새로운 문서들의 저장소. 보다 적당한 장소로 이동된다.
o 오래된 문서들의 저장소. 유예 기간으로 보관되고 있는 것들이다.
l 특정 시스템에 대한 로컬 문서들
출처: 모름(잘 정리된 것이 있어 긁어왔는데 출처를 깜빡했다.. 원문의 작성자 분께 죄송하다는 말씀 드리며, 삭제 요청 시 삭제하도록 하겠습니다.)

본격적으로 파일은 어떻게 만드느냐...
파일명은 NUMBER에 해당하는 숫자를 확장자로 넣어야 한다.
즉, 예를 들면,
$ vi /usr/local/man/myman.1
이런 방식이다.
기본적으로 /usr/local/man과 /usr/share/man 등의 folder에 주로 넣으며, 확장하고 싶으면 $(PATH)에 넣어두면 된다.
man page를 열어보면 알겠지만 헤더도 있고 자동으로 인덴트도 되어 있는 것을 볼 수 있다.
.SH + NAME / SYNOPSIS / DESCRIPTION / OPTIONS / SEE ALSO / COPYRIGHT / AUTHOR 등 구분을 하고
.TP / .PP로 행을 구분한다.

예시는 위에 언급한 폴더에 아무거나 열어보면 된다.

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에서 동적으로 만들어줌.