= Kernel API 5 - Linux Driver Model(ext) = -- [김도집] [[DateTime]] * [wiki:KernelApi Kernel API 1 - Core(1/2)] * [wiki:KernelApi1 Kernel API 1 - Core(2/2)] * [wiki:KernelApi2 Kernel API 2 - Extension] * [wiki:KernelApi3 Kernel API 3 - Linux Driver Model] * [wiki:KernelApi4 Kernel API 4 - Porting(ARM)] * [wiki:KernelApi5 Kernel API 5 - Linux Driver Model(ext)] [[TableOfContents]] == platform == 관련 자료형 및 함수에 대한 것은 [wiki:KernelApi Kernel API 1 - Core(1/2)] 를 참고하라. == sysdev == 시스템 디바이스(cpu, timer, rtc 등)를 위한 드라이버 모델이다. 관련 자료형 및 함수는 에 선언되어 있다. === sysdev_class === 에 선언되어 있다. {{{#!vim c struct sysdev_class { struct list_head drivers; int (*shutdown)(struct sys_device *); int (*suspend)(struct sys_device *, pm_message_t state); int (*resume)(struct sys_device *); struct kset kset; }}} === sysdev_class_register === 에 선언되어 있다. {{{#!vim c int sysdev_class_register(struct sysdev_class *); }}} === sysdev_class_unregister === 에 선언되어 있다. {{{#!vim c void sysdev_class_unregister(struct sysdev_class); }}} === sysdev_driver === 에 선언되어 있다. {{{#!vim c struct sysdev_driver { struct list_head entry; int (*add)(struct sys_device *); int (*remove)(struct sys_device *); int (*shutdown)(struct sys_device *); int (*suspend)(struct sys_device *, pm_message_t state); int (*resume)(struct sys_device *); }; }}} === sys_device === 에 선언되어 있다. {{{#!vim c struct sys_device { u32 id; struct sysdev_class *cls; struct kobject kobj; }; }}} === sysdev_register === 에 선언되어 있다. {{{#!vim c int sysdev_register(struct sys_device *); }}} 관련함수: sysdev_unregister === sysdev_unregiser === 에 선언되어 있다. {{{#!vim c void sysdev_unregister(struct sys_device *); }}} 관련함수: sysdev_register === sysdev_attribute === 에 선언되어 있다. {{{#!vim c struct sysdev_attribute { struct attribute attr; ssize_t (*show)(struct sys_device *, char *); ssize_t (*store)(struct sys_device *, const char *, size_t); }; }}} === SYSDEV_ATTR === 에 선언되어 있다. sysdev_attribute형의 attr_##name으로 자료 구조체를 만드는 매크로이다. {{{#!vim c SYSDEV_ATTR(_name, _mode, _show, _store) }}} === sysdev_create_file === 에 선언되어 있다. {{{#!vim c int sysdev_create_file(struct sys_device *, struct sysdev_attribute *); }}} 관련함수: sysdev_remove_file === sysdev_remove_file === 에 선언되어 있다. {{{#!vim c void sysdev_remove_file(struct sys_device *, struct sysdev_attribute *); }}} 관련함수: sysdev_create_file == firmware == 일부 디바이스의 경우엔 firmware를 로드하거나 업데이트할 필요가 있다. 이러한 경우를 위하여 리눅스 2.6의 sysfs를 이용하여 사용자 수준에서 firmware 데이터를 커널 수준으로 로드할 수 있다. firmware와 관련된 것들은 에 선언되어 있다. ||'''함수'''||'''설명'''|| ||request_firmware|||| ||request_firmware_nowait|||| ||release_firmware|||| === struct fw === firmware 인터페이스에서 사용하는 기본 자료형은 {{{struct fw;}}}가 있다. {{{#!vim c struct firmware { size_t size; u8 *data; }; }}} ==== request_firmware === sysfs를 통해 사용자 수준의 데이터를 커널 수준으로 넘겨 받는다. {{{#!vim c int request_firmware(const struct firmware **fw, char *name, struct device *device); }}} 넘겨 받은 데이터는 fw 구조체 내에 저장이 된다. 넘겨 받은 firmware 데이터의 이름은 name으로 설정한다. device는 firmware와 관련된 디바이스이다. 실제 데이터는 fw->data에 있으며, 그 크기는 fw->size가 되는 것이다. 따라서 이 값을 디바이스에 로드하거나 업데이트하면 된다. === request_firmware_nowait === request_firmware는 firmware를 요구 받았을 때 완료되기까지 휴면상태가 되는데, request_firmware_nowait는 휴면되지 않는다. {{{#!vim c int request_firmware_nowait(struct module *module, char *name, struct device *device, void *context, void (*cont)(const struct firmware *fw, void *context)); }}} === release_firmware === request_firmware를 통해 받은 firmware 데이터에 대한 자원 할당을 해제한다. {{{ void release_firmware(struct firmware *fw); }}} === firmware의 사용 === 사용자 수준에서는 {{{/sys/class/firmware}}} 디렉토리 아래에 디바이스 이름의 디렉토리가 만들어진다. 그 아래에 loading, data, device 등의 파일 또는 심볼릭 링크가 만들어진다. loading은 현재 firmware의 로딩이 완료되면 0을 쓰고, 로딩을 중단한다면 -1, 이외의 값은 로딩 중임을 의미한다. data를 통해 firmware 데이터를 write하면 된다. device는 /sys/device에서 해당 디바이스에 대한 심볼릭 링크이다. 경우에 따라서 firmware를 로딩하는 시간이 길어지면 timeout이 걸리는데, 이는 {{{/sys/class/fimrware/timeout}}}를 통해 timeout 시간을 변경할 수 있다.