임베디드 리눅스 커널 프로그래밍(2) - 커널 데이터타입, 커널 인터페이스 함수

커널 Data Type
커널에서는 C언어의 원래 자료형 대신에 typedef로 정의된 자료형이 많이 사용된다.
커널에서 여러 종류의 값을 나타나는 데에 int나 long 등을 사용하는 대신 접미사 _t로 끝나는 자료형을 많이 사용한다.
- pid_t, uid_t, gid_t, dev_t, size_t, ...
- <linux/types.h>에 정의되어 있음
데이터의 크기를 명시적으로 표현한 자료형도 사용한다.
- u8, u16, u32, s8, s16, s32 (커널 코드에서만 사용 가능)
u -> unsigned / s -> signed - 사용자 프로그램에서는 __u8, __s8과 같이 _를 두 개 붙여서 사용함
- <asm/types.h>에 정의되어 있음
Kernel Interface 함수
커널 프로그램은 일반적인 라이브러리를 사용하지 못하고 커널에서 export한 함수들만 사용이 가능하다.
커널 인터페이스 함수의 분류는 아래와 같다.
- I/O port, I/O memory
- Interrupt
- Memory
- Synchoronization
- Kernel Message 출력
- Device Driver register
Kernel Interface 함수 - port I/O
1. I/O에 대한 가상주소 맵핑
void *ioremap(unsigned long phys_addr, unsigned long size); //physical주소를 가상주소로 맵핑 void *ioremap_nocache(unsigned long phys_addr, unsigned long size);//캐시에 복제하지 말란 뜻 void iounmap(void * addr); //맵핑한거 해제
2. I/O memory 읽기
unsigned int ioread8(void *addr); //8비트 읽기 unsigned int ioread16(void *addr); //16비트 읽기 unsigned int ioread32(void *addr); //32비트 읽기
3. I/O memory 쓰기
void iowrite8(u8 value, void *addr); //8비트 쓰기 void iowrite16(u16 value, void *addr); //16비트 쓰기 void iowrite32(u32 value, void *addr); //32비트 쓰기
4. I/O port 입출력 (x86)
unsigned inb(unsigned port); void outb(unsigned char byte, unsigned port);
Kernel Interface 함수 - Interrupt
1. 인터럽트 비활성화/활성화 (macro)
local_irq_disable(); local_irq_enable();
2. 인터럽트 비활성화/활성화 시 status register 저장/복원 (macro)
unsigned long flags; local_irq_save(flags); local_irq_restore(flags);
3. 인터럽트 핸들러 등록/해제
//등록 int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long irqflags, const char *devname, void* device); //해제 void free_irq(unsigned int irq, void *devid);
Kernel Interface 함수 - Memory
1. 커널 물리적 메모리 동적 할당/해제
void *kmalloc(size_t size, int flags); //할당 void kfree(void *obj); //해제
- 커널 메모리 할당 : 최대 크기 제한 있음. (초기 128KB, 현재 증가함)
- 물리적 주소 공간에서 연속적인 메모리를 할당한다.
- flags : GFP_USER(사용자 프로그램용 메모리 할당), GFP_KERNEL(커널용 메모리 할당, sleep가능), GFP_ATOMIC(인터럽트 핸들러 등에서 사용, sleep불가) 등
2. 커널 가상 메모리 동적 할당/해제
void *vmalloc(unsigned int len)
- 커널 메모리 할당, 크기 제한 없음
- 가상 주소 공간에서 연속적인 메모리 영역을 할당
void vmfree(void *addr)
- vmalloc()에서 할당받은 커널 메모리를 반납
Kernel Interface 함수 - 데이터 복사
1. 사용자 공간과 커널 공간 사이에 데이터 복사
unsigned long copy_from_user(void *to, const void *from, unsigned long n); unsigned long copy_to_user(void *to, const void *from, unsigned long n); put_user(data, ptr); get_user(ptr) (macro);
- ptr이 가리키는 사용자 공간에 data를 전달(put)하거나 가져옴(get)
- ptr의 타입에 따라서 복사할 데이터 크기를 인식함.
- 커널 공간에서 사용자 공간의 메모리를 읽고 쓰는데 접근할 수 있는지를 검사하는 동작을 포함
2. 메모리 값 설정
void *memset(void *s, char c, size_t count); //메모리에 s에 c를 count만큼 복사
Kernel Interface 함수 - Synchronization
동기화 관련 함수들
void sleep_on(struct wait_queue **q); // deprecate void sleep_in_interruptible(struct wait_queue **q); // deprecate //q의 번지를 event로 sleep하며, uninterruptible/interruptible wait_event(queue, condition);//(macro) wait_event_interruptible(queue, condition); /*condition이 1일 때까지 wait, queue번지를 event로 하여 sleep하며 uninterruptible/interruptible*/ void wake_up(struct wait_queue **q); void wake_up_interruptible(struct wait_queue **q); //sleep_on, wait_event에 의해 sleep한 task를 깨움
Kernel Interface 함수 - 메시지 출력
표준 출력으로는 printk 함수를 사용한다.
printk(const char *fmt, ...); printk(LOG_LEVEL message); //예시 printk("<1>Hello, World!"); printk(KERN_WARNING "warning...\n"); //<4>
LOG_LEVEL은 <linux/kernel.h>를 참조하자.
=> KERN_EMERG, KERN_ALERT, KERN_ERR, KERN_WARNING, KER_INFO, KERN_DEBUG
Kernel Interface 함수 - device driver 관련
디바이스 드라이버 관련해서는 상당히 중요한데, 등록/해체하는 함수들은 아래와 같다.
1. 등록
int register_xxxdev(unsigned int major, const char *name, struct file_operations *fops);
- character / block driver를 xxxdev[major]에 등록한다.
- xxx : chr 또는 blk
2. 해제
int unregister_xxxdev(unsigned int major, const char *name);
- xxxdev[major]에 등록되어 있는 디바이스 드라이버를 제거한다.
3. 네트워크 디바이스 드라이버의 경우 등록/해제
int register_netdev(struct net_device *dev); int unregister_netdev(struct net_device *dev);
4. 장치번호 dev로부터 major/minor 번호 구하는 함수
MAJOR(kdev_t dev); MINOR(kdev_t dev);
Kernel Interface 함수 - signal 함수
디바이스 드라이버에서 사용자 프로그램에 signal을 보내는 함수.
//예시 int kill_proc(pid_t pid, int signum, int priv);
pid (process id)
- current : 현재 프로세스 task_struct에 대한 ptr(macro)
- current -> pid : 현재 프로세스의 pid
- cureent -> ppid : 현재 프로세스의 부모 프로세스의 pid
사용자 프로그램에서 signal handler 등록하는 함수
void (*signal(int signum, void(*handler)(int)) (int);
'Computer Engineering > 임베디드 시스템' 카테고리의 다른 글
리눅스 디바이스 드라이버 프로그래밍(1) - 디바이스 드라이버 개요, 디바이스 드라이버 종류 (0) | 2019.06.12 |
---|---|
임베디드 리눅스 커널 프로그래밍(3) - 시스템 호출 함수 구현 (0) | 2019.06.12 |
임베디드 리눅스 커널 프로그래밍(1) - application 프로그래밍과 커널프로그래밍의 차이점, 커널프로그래밍 시 주의사항 (2) | 2019.06.11 |
ABI와 EABI (0) | 2019.06.11 |
툴체인(Tool Chain)이란 (0) | 2019.06.11 |
댓글
이 글 공유하기
다른 글
-
리눅스 디바이스 드라이버 프로그래밍(1) - 디바이스 드라이버 개요, 디바이스 드라이버 종류
리눅스 디바이스 드라이버 프로그래밍(1) - 디바이스 드라이버 개요, 디바이스 드라이버 종류
2019.06.12Device와 Device Driver Device 네트워크 어댑터, LCD 디스플레이, 오디오, 터미널, 키보드, 하드디스크, 플로피디스크, 프린터 등과 같은 주변 장치들을 말함. 디바이스의 구동에 필요한 프로그램, 즉 디바이스 드라이버가 필수적으로 요구됨 Device Driver 실제 장치 부분을 추상화시켜 사용자 프로그램이 정형화된 인터페이스를 통해 디바이스를 접근할 수 있도록 해주는 프로그램 디바이스 관리에 필요한 정형화된 인터페이스 구현에 요구되는 함수와 자료구조의 집합체 표준적으로 동일 서비스 제공을 목적으로 커널의 일부분으로 내장 응용 프로그램이 하드웨어를 제어할 수 있도록 인터페이스 제공 하드웨어 독립적인 프로그램을 작성할 수 있도록 함. 리눅스 디바이스 드라이버 사용자 관점에서의 디바이스… -
임베디드 리눅스 커널 프로그래밍(3) - 시스템 호출 함수 구현
임베디드 리눅스 커널 프로그래밍(3) - 시스템 호출 함수 구현
2019.06.12시스템 호출(System Call)이란? 시스템 호출(system call)은 운영 체제의 커널이 제공하는 서비스에 대해 응용 프로그램의 요청에 따라 커널에 접근하기 위한 인터페이스다. 보통 C나 C++과 같은 고급 언어로 작성된 프로그램들은 직접 시스템 호출을 사용할 수 없기 때문에 고급 API를 통해 시스템 호출에 접근하게 하는 방법이다. 시스템 호출 과정 시스템 호출의 구현 시스템 호출을 구현하는 sequence는 위와 같다. 아래는 sys_hello라는 시스템 호출 함수를 만드는 예시이다. 1) 시스템 호출 함수 정의 Kernel 소스의 kernel 디렉토리에 시스템 호출 함수를 정의한 프로그램 파일 (hello.c) 생성 #include asmlinkage void(sys_hello(){ pri… -
임베디드 리눅스 커널 프로그래밍(1) - application 프로그래밍과 커널프로그래밍의 차이점, 커널프로그래밍 시 주의사항
임베디드 리눅스 커널 프로그래밍(1) - application 프로그래밍과 커널프로그래밍의 차이점, 커널프로그래밍 시 주의사항
2019.06.11Kernel Programming 이란? 커널 모드에서 수행하는 프로그램을 작성하는 것을 말한다. 커널 프로그래밍의 종류는 아래와 같다. Linux Kernel core 기능 추가 Linux Kernel 알고리즘 개선 Linux Kernel 모듈 프로그래밍 - 커널 컴파일 필요 없음 (나는 주로 세번째인 모듈 프로그래밍을 했다. 나머지는 차차 포스팅 할 예정) Kernel Programming vs Application Programming 수행 방법에서의 차이 Application program : 처음부터 순차적으로 수행함 Kernel : 응용 프로그램이 호출한 system call이나 interrupt handler를 수행하기 위해 비동기적으로 수행함 라이브러리 Application program … -
ABI와 EABI
ABI와 EABI
2019.06.11ABI (Application Binary Interface)란 응용 프로그램과 운영체제 또는 라이브러리와의 표준화된 인터페이스를 제공하는 것을 말한다. ABI는 서로 다른 컴파일러가 만든 오브젝트 파일을 연결하여 사용할 수 있게 한다. Application 간 binary 데이터를 어떻게 교환하는지 다음과 같은 규칙들을 정한다. 데이터 타입과 정렬방법 함수 호출 시 인수 및 결과에 대한 레지스터 교환 방법 시스템 콜 호출 방법 프로그램 코드의 시작과 데이터에 대한 초기화 방법 파일 교환 방법 (ELF 등) API랑 뭐가 다른거지? ABI는 API보다 저수준(binary)란 점. 그리고 API는 소스코드에서 사용되고 ABI는 바이너리에서 호환이 된다는 점에서 다르다. 아키텍쳐와 운영체제마다 조금씩 차이가…
댓글을 사용할 수 없습니다.