FSTWikiRev. 1.28 KernelApi
Login:
Password:
Join
E D R S I H P RSS
FrontPage|FindPage|TitleIndex|RecentChanges

Kernel API #

-- 김도집 2005-09-22 14:20:31

Contents

1 Kernel API 1 - Core (1/2)
1.1 서론
1.2 기본 자료형
1.3 주요 헤더 파일들
1.4 비트 연산
1.4.1 set_bit
1.4.2 clear_bit
1.4.3 change_bit
1.4.4 test_and_set_bit
1.4.5 test_and_clear_bit
1.4.6 test_and_change_bit
1.4.7 test_bit(nr,p)
1.5 initcall/exitcall
1.6 디바이스 등록 및 해제
1.6.1 struct platform_device
1.6.1.1 to_platform_device
1.6.1.2 platform_device_register
1.6.1.3 platform_device_unregister
1.6.1.4 platform_device_register_simple
1.7 드라이버 등록 및 해제
1.7.1 platform_driver
1.7.1.1 platform_driver_register
1.7.1.2 platform_driver_unregister
1.7.1.3 platform_get_drvdata/platform_set_drvdata
1.7.2 device_driver
1.7.2.1 driver_register
1.7.2.2 driver_unregister
1.7.2.3 dev_set_drvdata
1.7.2.4 dev_get_drvdata
1.8 문자 디바이스 드라이버
1.8.1 어떤 API를 사용할 것인가
1.8.2 chrdevs vs cdev_map
1.8.3 문자 디바이스 드라이버 API
1.8.3.1 struct file_operations
1.8.3.2 register_chrdev
1.8.3.3 unregister_chrdev
1.8.3.4 struct cdev
1.8.3.5 cdev_init
1.8.3.6 cdev_add
1.8.3.7 cdev_del
1.8.3.8 register_chrdev_region
1.8.3.9 alloc_chrdev_region
1.8.3.10 unregister_chrdev_region
1.9 장치 번호
1.9.1 MKDEV
1.9.2 MAJOR
1.9.3 MINOR
1.10 프로세스
1.10.1 스케줄링
1.10.1.1 schedule_timeout
1.10.1.2 set_current_state
1.10.1.3 wait_event_interruptible
1.10.1.4 wake_up_interruptible
1.11 타임(타이머)
1.11.1 ?BogoMIPS
1.11.2 loops_per_jiffy
1.11.3 jiffies
1.11.4 커널 타이머
1.11.4.1 자료 구조
1.11.4.2 TIMER_INITIALIZER
1.11.4.3 init_timer
1.11.4.4 add_timer
1.11.4.5 del_timer
1.11.4.6 mod_timer
1.11.5 High-resolution 커널 타이머
1.11.5.1 hrtimer_init
1.11.5.2 hrtimer_start
1.11.5.3 hrtimer_cacel
1.11.5.4 hrtimer_restart
1.11.5.5 hrtimer_get_remaining
1.11.5.6 hrtimer_get_res
1.11.5.7 hrtimer_active
1.11.5.8 hrtimer_forward
1.11.5.9 hrtimer_nanosleep
1.12 메모리
1.12.1 사용자/커널 공간
1.12.1.1 copy_from_user
1.12.1.2 copy_to_user
1.12.1.3 get_user
1.12.1.4 put_user
1.12.1.5 verify_area
1.12.1.6 access_ok
1.12.2 메모리 매핑
1.12.2.1 remap_page_range
1.12.2.2 remap_pfn_range
1.12.2.3 get_user_pages
1.12.3 IO 메모리 매핑
1.12.3.1 request_mem_region / release_mem_region
1.12.3.2 ioremap
1.12.3.3 iounmap
1.12.3.4 io_remap_pfn_range
1.12.3.5 readb/w/l
1.12.3.6 writeb/w/l
1.12.4 커널 메모리
1.12.4.1 kmalloc
1.12.4.2 kzalloc
1.12.4.3 vmalloc
1.12.4.4 kmem_cache_create
1.12.4.5 kmem_cache_alloc
1.12.4.6 kmem_cache_free
1.12.4.7 kmem_cache_destroy
1.12.4.8 get_zeroed_page
1.12.4.9 __get_free_page
1.12.4.10 __get_free_pages
1.12.5 유용한 매크로
1.13 MMAP
1.13.1 dma_mmap_writecombine
1.13.2 dma_free_writecombine
1.13.3 io_remap_pfn_range
2 DMA
2.1 메모리 할당
2.1.1 dma_alloc_coherent
2.1.2 dma_alloc_writecombine
2.1.3 Streaming DMA
2.1.4 dma_map_single
2.1.5 dma_unmap_single
2.1.6 dma_sync_single_for_cpu
2.1.7 dma_sync_single_for_device
2.2 DMA POOL
2.2.1 dma_pool_create
2.2.2 dma_pool_destroy
2.2.3 dma_pool_alloc
2.2.4 dma_pool_free

1.1 드라이버 등록 및 해제 #

1.1.1 관련 자료형 #

driver_register/device_unregister 함수에서 사용하는 자료형은 <linux/device.h>에 선언되어 있다.
struct device_driver {
  const char *name;
  struct bus_type *bus;

  struct completion unloaded;
  struct kobject kobj;
  struct klist klist_devices;
  struct klist_node knode_bus;

  struct module *owner;

  int (*probe) (struct device *dev);
  int (*remove) (struct device *dev);
  int (*shutdown) (struct device *dev);
  int (*suspend) (struct device *dev, pm_message_t state, u32 level);
  int (*resume) (struct device *dev, u32 level);
};

필드설명
name디바이스 드라이버의 이름을 문자열 형으로 지정한다 (필수)
bus보통은 &platform_bus_type으로 지정한다 (필수)
unloaded
kobj내부적으로 드라이버 객체를 관리하기 위한 것으로 직접적으로 사용하지 않는다 (임의 지정하지 않는다)
klist_devices
knode_bus
owner
probe()디바이스의 초기화 루틴이다 (필수)
remove()디바이스가 제거될 때 호출되는 루틴이다 (필수)
shutdown()
suspend()절전모드로 들어갈 때 호출된다 (필수)
resume()절점모들 빠져나올 때 호출된다 (필수)
/!\ 위 테이블에서 foo()와 같이 ()가 붙은 필드는 함수(포인터)를 의미한다.

1.1.2 driver_register #

버스를 갖는 드라이버를 등록할 때 사용하는 함수이다. 함수의 원형은 다음과 같다:
int driver_register(struct device_driver *drv);

관련함수: driver_unregister

static struct device_driver foo_driver = {
  .name    = "foo”,
  .bus     = &platform_bus_type,
  .probe   = foo_probe,
  .remove  = foo_remove,
  .suspend = foo_suspend,
  .resume  = foo_resume,
};

static int __init foo_init(void) {
  int err;

  err = driver_register(&foo_driver);

  return err;
}

1.1.3 driver_unregister #

driver_register()를 통해 등록된 드라이버를 해제할 때 사용한다. 함수의 원형은 다음과 같다:
void driver_unregister(struct device_driver *drv)

관련함수: driver_register

1.2 메모리 #

1.2.1 사용자/커널 공간 #

메모리 영역은 사용자 영역과 커널 영역으로 나뉜다. 일반적으로 사용자 영역의 경우 page out(swap out)된 경우가 있을 수 있다. 이런 메모리 공간을 커널 영역에서 직접 접근하는 경우 page fault 등이 생길 수 있는데, 커널 공간의 일부 처리 중에는 이러한 것이 문제가 될 수 있다.

반대로 커널 영역의 메모리는 사용자 영역의 프로세스에서 직접 접근할 수 없다.

따라서 서로 다른 영역을 메모리를 접근하기 위해서는 이에 필요한 적절한 API를 이용해야 한다.

1.2.1.1 copy_from_user #

사용자 영역의 메모리에 있는 데이터를 커널 영역의 메모리 영역으로 복사할 때 사용하는 함수이다. 이 함수는 아키텍처에 의존적인 함수로 <asm/uaccess.h> 헤더 파일에 선언되어 있다.

unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)

매개변수설명
to커널 영역의 메모리 주소
from사용자 영역의 메모리 주소
n바이트 단위의 데이터 크기

성공하면 0을 반환하고 실패하면 0이 아닌 값을 반환한다.

관련함수: copy_to_user

/!\ 함수 내부적으로 access_ok를 통해 사용자의 메모리 영역을 검사하므로 별도의 access_ok를 호출할 필요는 없다.

1.2.1.2 copy_to_user #

unsigend long copy_to_user(void __user *to, const void *from, unsigned long n)

1.2.1.3 get_user #

사용자 영역의 데이터를 커널 영역으로 복사할 때 사용한다. 이는 아키텍처 의존적인 함수로 <asm/uacess.h>에 선언되어 있다.

int get_user(void *to, void *from)

1.2.1.4 put_user #

커널 영역의 데이터를 사용자 영역으로 복사한다. 이는 아키텍처 의존적인 함수로 <asm/uaccess.h>에 선언되어 있다.

int put_user(void *from, void *to)

1.2.1.5 access_ok #

사용자 영역의 메모리가 유효한지 검사한다. <asm/uaccess.h>에 선언되어 있다.

int access_ok(int type, void *addr, unsigned long size);

매개변수설명
type어떤 유효 검사를 할지를 결정한다. 다음 표를 참조
addr유효 검사를 시작할 주소
size유효 검사를 할 영역의 바이트 단위 크기

type 매개 변수는 매크로로 선언되어 있는데, 다음과 같다:
type설명
VERIFY_READ읽기에 대한 유효 검사
VERIFY_WRIT쓰기에 대한 유효 검사

/!\ 다른 함수와 달리 유효하다면 0이 아닌 값을 반환하고 유효하지 않다면 0을 반환한다.

copy_from_user/copy_to_user 또는 get_user/put_user 등의 함수는 access_ok를 사용할 필요가 없다. __get_user 등과 같이 더 저 수준의 함수를 직접 호출하여 사용할 때만 사용하게 된다.

다음은 access_ok를 사용한 예이다.
static inline unsigned long copy_from_user(void *to, const void __user *from,
 unsigned long n)
{
  if (access_ok(VERIFY_READ, from, n))
    n = __arch_copy_from_user(to, from, n);
  else
    memzero(to, n);
  return n;
}

1.3 사운드(Sound) #

1.3.1 ALSA #

1.3.1.1 자료 구조 #

snd_card_t는 <sound/core.h>에 정의 되어 있다. 이는 strcut _snd_card 의 typedef형이다.
struct _snd_card {
  char driver[16];     /* 드라이버 이름 */
  char shortname[32];  /* 사운드 카드의 짧은 이름 */
  char longname[80];   /* 사운드 카드의 이름 */

  void *private_data;  /* 사운드 카드에 대한 추가 정보 */
  void (*private_free) (snd_card_t *card);  /* 추가 정보을 위해 할당받은 자원 */
                                            /* 반환을 위한 콜백 */
/!\ 위 구조체의 필드는 위 명시된 내용 외에도 무수히 많다. 사용자가 꼭 알아야 하는 것들만 나열했다.

1.3.1.2 snd_card_new #

사운드 카드의 구조체를 할당 받는다.
snd_card_t *snd_card_new(int idx, const char *xid,
                         struct module *module, int extra_size)

매개변수설명
idx카드의 인덱스(주소),0에서 (SNDRV_CARDS-1)
xid카드 이름 (문자열)
modulelocking을 소유한 상위 모듈
extra_size사운드카드 구조체 이후 추가 할당받을 메모리 크기

성공하면 snd_card_t형의 포인터를 반환하고 실패하면 NULL을 반환한다.

snd_card_t *card;

card = snd_card_new(-1, id, THIS_MODULE, sizeof(foo_bar));
if (card == NULL)
  return -ENOMEM;

1.3.1.3 snd_card_register #

사운드 카드를 등록한다.

int snd_card_register(snd_card_t *card)

성공하면 0을 반환하고, 실패하면 0이 아닌 값을 반환한다.

1.3.1.4 snd_card_set_pm_callback #

전원 관리를 위한 콜백을 등록한다.

int snd_card_set_pm_callback(snd_card_t *card,
                             int (*suspend)(snd_card_t *, pm_message_t),
                             int (*resume)(snd_card_t *),
                             void *private_data)

필드설명
card사운드카드 구조체
suspend절전 모드 진입시 호출되는 콜백
resume절전 모드 해제시 호출되는 콜백
private_data콜백에 넘길 매개 변수의 포인터

항상 0을 반환한다.

이 함수는 매개변수 card의 필드 중 pm_suspend, pm_resume, pm_private_data 를 넘겨주는 매개 변수의 값으로 설정한다.

snd_card_set_pm_callback(card, snd_foo_suspend, snd_foo_resume, foo);

last modified 2007-03-11 13:55:12
ShowPage|FindPage|DeletePage|LikePages Valid XHTML 1.0! Valid CSS! powered by MoniWiki
3.5990 sec