1. 임베디드 시스템 설계
임베디드 시스템 : 하드웨어, 운영체제, 응용소프트웨어, 네트워킹 등을 특수 목적에 맞게 최적화한 시스템
초기 제어용 시스템 : 간단한 하드웨어 + 간단한 실시간 운영체제 + 고정된 응용프로그램
현재 다양한 임베디드 시스템 : 정보가전시스템, 이동단말기
전용 하드웨어와 고정된 기능의 임베디드 시스템에서 일반화된 시스템에 소프트웨어를 교체하는 형태로 진화
하드웨어 : 주 프로세서 + 제어를 위한 장치 인터페이스
소프트웨어 : 임베디드 운영체제 + 응용 프로그램
개발환경 : 교차 개발 환경, 개발 호스트 시스템, 개발 타겟 시스템
SOC : 하나의 칩에 프로세서, 메모리, 입출력 제어 회로를 포함한 임베디드 시스템을 위한 패키지
X86 : Intel, 임베디드에는 사용율 낮음
ARM : Advanced RISC Machine, ARM Holdings, 동일한 명령어 집합을 사용하므로 binary code수준의 호환성, JTAG 디버거가 넓게 사용
IBM/Motorola PowerPC : IBM, Motorola, Apple, 리눅스가 잘 지원.
MIPS : 다양한 명령어 집합 구현, 리눅스 지원 잘 안함
Hitachi SuperH : 게임콘솔
Motorola 68000 : 리눅스는 지원하지만 리눅스 소프트웨어들이 지원 안함
리눅스
Linus Tovalds. 1991년 0.0.1 버전, Minix기반, copyleft,
버전 중간 자리 짝수 : stable kernel, 홀수 : development kernel
Its free(open source), it’s popular(arm, Pentium, sparc, alpha, m68k, powerpc, mips), it’s powerful, it’s under your control(내부를 볼 수 있음), it’s robust(say goodbye to the blue screen), it’s full-featured(multi-thread, advanced networking, gui), it’s small(1mb 이하의 커널), it’s big(powerful utilities and applications), it’s well documented, it’s sexy)
Unix
1969년 bell사에서 ken Thompson, dennis ritchie가 개발, v3부터 c로 작성.
Bsd : Berkly에서 개발. 정부 사용 목적
Simple is beautiful, 고급언어로 작성, 시분할 시스템, shell 지원, 트리 구조의 파일 시스템, 장치/객체를 파일로 접근, 일반 파일은 단지 문자열로 해석, 다중 프로세서 지원, 소켓 지원, ipc지원, 다양한 cpu지원
파일이라는 장소에 프로세스(태스크)라는 생명을 제공한다.
파일 : stream of bytes, 많은 객체를 동일한 파일 인터페이스로 접근 가능
프로세스 : 수행중인 프로그램, 스케줄링의 대상
디렉토리 : a set of files, 계층 구조를 제공
상태정보 : ps, pstree, top
파이프
프로세스 : fork, exec, kill
시스템 호출 : os가 제공하는 함수, 커널 수준에서 수행됨
라이브러리 : 사용자 편의를 위해 제공되는 함수들의 집합, 사용자 수준에서 실행됨
Shell : 명령어 해석기
Commands : 명렁어로 시스템과 대화
Library : 자주 사용하는 오브젝트 파일들의 집합
S/W 개발 단계 : 컴파일러(gcc, .c -> .s) -> 어셈블러(as, .s->.o) -> 링커(ld, .o -> 실행파일, library파일 결합) -> 로더 -> 디버거
High level language -> assembly language -> machine language binary code
디버거 : ddd
2. linux 명령어, vi 편집기, makefile
Shell : 사용자를 위한 인터페이스를 제공해주는 소프트웨어
파일시스템 : 저장장치에 파일 형태로 데이터를 저장하는 운영체제 내부의 코드, linux는 ext4 파일시스템
Super-block : 디스크의 물리적 정보, 파일 시스템 내 inode 개수, 총 데이터 블록 개수 등 전체 파일 시스템과 관련된 정보 유지
Inode : 파일, 디렉토리 마다 대응되는 inode가 존재, 파일에 대한 이름을 제외한 모든 정보 저장(데이터블록번호)
디렉토리 파일 : 디렉토리 내에 존재하는 파일이나 서브디렉토리 정보를 테이블 형태로 유지, inode+이름으로 구성된 형태
특수파일 : /dev 에 존재, 디바이스를 대표하는 파일, 문자 특수 파일, 블록 특수 파일
소켓 : 컴퓨터 사이에 데이터 통신을 위한 인터페이스
네임드 파이프 : 파일 시스템에 이름을 부여하고 생성한 파이프 파일, 두 프로세스간 데이터 전달을 중계
/dev : 디바이스 드라이버들, 시스템 디바이스나 자원들을 액세스 하는 데 사용
/etc : 설정파일, 프로그램, 유틸리티, 관리자에 의해 사용, 설정파일들 및 초기 스크립트 파일
/lib : 공유 라이브러리 이미지
/proc : 가상 파일 시스템. 시스템에 운영되고 있는 다양한 프로세서들에 관한 내용과 프로그램에 대한 정보
/usr : 응용 패키지, program files
/opt : add-on 소프트웨어 패키지
/mnt : 각종 입출력장치와 연결할 때 사용, 마운트하면 해당 파일시스템의 내용이 이곳에 놓이게 됨
/var : 시스템 작동 중 변경되는 파일들, 로그파일, 스풀파일
/lost+found : fsck에 의해 사용되는 디렉토리
/media : usb, cd-rom, floppy disk mount
/boot : 부팅에 관련한 모든 파일
/sbin : standalone binary 디렉토리. 시스템 운영에 필요한 명령어 포함, halt, shutdown 명령어
Foreground 명령어 : 쉘이 명령을 실행시키고 쉘 자신은 명령 실행이 종료될 때 까지 대기
Background 명령어 : & 붙임, 쉘은 백그라운드로 명령을 실행시킴과 동시에 쉘 자신도 실행하여 다음 명령 입력을 대기. 쉘이 터미널 입출력 권한을 가짐. 백그라운드로 실행되는 명령은 터미널 입출력 권한이 없음. 터미널 입출력을 요청하면 중단됨.
Cat 후 ctrl + d
b: 블록 특수 파일 C: 문자 특수 파일 d : 디렉토리 파일 l : 심볼릭 링크 P : 파이프 파일 s : 소켓 파일
chmod 644 abc.txt
chomd g+w test, chomd g-w test, chmod g+wx test, chmod o=g test
umaks 022 = 666 – 022 = 644
setuid, setgid : 실행 파일을 실행할 때 파일의 소유자 권한으로 실행(권한이 있어야 세팅가능)
chmod 4700 abc.txt -> 기존권한 700+setuid 4000 , chmod 2700 abc.txt -> 기존권한 700+setgid 2000
find : 이름, 사이즈, 소유자, 날짜와 같은 특정 조건을 가진 파일 또는 디렉토리 찾는 명령
-name, -type, -user, -size, -newer, -empty. Find –name my* -size -2000c(2000byte이하) -2k(2kilobyte이하)
-exec : 찾아낸 파일에 대한 특정 명령 사용 가능. Find . –type f –name *.txt –exec rm –f {}
More : space – 다음 페이지, enter – 한 라인씩
Less : more와 비슷하나 앞 뒤로 움직이면서 볼 수 있음
Cmp : 다른점 출력
Diff : 차이점을 줄 단위로 비교하여 출력
Grep : 파일 안에서 특정 패턴을 찾아 출력. Find / -print | grep myfile.c
Gedit, vi, emacs
Vi에서 파일 호출 한 경우 버퍼에 저장되어 수정되며 다시 하드디스크에 저장
:숫자 -> 해당 줄로 이동, 숫자d -> d만큼 삭제, u -> undo, r-> redo
Makefile 구조 : 목표, 의존관계, 명령으로 구성
Target : dependeny
Command
File1.o: file1.c $(headers) makefile = $objs: $($@:.o=.c) $(headers) makefile $< == .c
$* : 확장자 없는 목표, $@ : 현재 목표, $<, $? : 현재 목표보다 더 최근에 갱신된 파일 이름
모듈단위최적화 : 실행시간 비중이 큰 함수 최적화, profiler, gprof, vtune
Unsigned 정수 사용, 자주 사용되는 변수는 register 키워드 사용
나눗셈, 나머지 연산 피하기.
배열을 이용하여 결과 리턴, 로컬에서 계산 후 글로벌 변수 변경, 구조체 인자인 경우 포인터로 전달, 포인터 참조 최소화, breakdown, switch보다 배열 사용, 0을 종료값으로 loop, 함수에서 루프 사용, 4개 이하의 인자 사용
__inline 키워드 사용 -> 함수 호출 비용은 줄이지만 코드의 크기 증가
3. ARM Processor와 Hunis 타겟보드 소개, 개발환경 설치
RISC 구조 : 제한된 수의 명령어, 고정길이 명령어, 빠른 실행 가능, ARM, MIPS
CISC 구조 : 많은 명령어, 가변길이 명령어, 복잡한 명령어는 다수의 클럭 사이클이 필요. PENTIUM
RISC : 쉽게 최고의 성능으로 최적화 가능, 빠른 실행 가능, 효율적인 파이프라인, 프로그램 코드 크기가 크지만 ARM은 THUMB모드로 해답을 제공
ARM : LOAD-STORE구조, 32BIT 고정길이 명령어, 15개 범용 레지스터, 명령어 파이프라인
사용자 모드에서는 최대 13개 범용 레지스터
PSR : Program Status Register
R13 = StackPointer, R14 = LinkRegister, R15 = ProgramCounter
인터럽트
FIQ : high priority fast hardware interrupt, 모든 다른 인터럽트들을 DISABLE
IRQ : regular hardware interrupt
SWI : 프로세서를 SUPERVISOR모드로 변경, SUPERVISOR의 SP, LP, PSR을 액세스, 레지스터 또는 스택으로 전달
SWI 우선순위 < IRQ, FIQ
THUMB모드 : 16비트 모드, Thumb instruction set -> 실행 시 32비트 명령어로 매핑, CPSR BIT5를 설정, small code size
3단계 명령어 파이프라인 : fetch, decode, execute
5단계 : 3단계 + data(필요한 경우 데이터 메모리 액세스), write-back(수신지 메모리에 명령 결과 기록)
Arm7 : 3단계 파이프라인, 32비트 주소, 32비트 데이터 버스
Arm9 : 5단계 파이프라인, 데이터 메모리와 코드 메모리 분리
Strong arm : arm9기반으로 intel에서 최적화, set-associative data and instruction cache, 향상된 multiplier, 많은 주변장치 지원 하드웨어 추가
Apt-get install minicom lrzsz(z-modem 프로그램)
4. cross 개발환경 설치, 타겟보드 리눅스 빌드
Cross 개발환경 : 커널을 올리기 전엔 타겟에 아무 프로그램도 없음. 메모리 용량이 적어 compiler올리기에 무리, processor가 다른 경우 target에서 돌아갈 수 있는 컴파일러 필요
Toolchain : host system의 cross compile 환경을 뜻함, 여러 개의 패키지 필요
Binutils : 어셈블러 및 로더 기타 툴
Glibc : cross compiler library and 일반 library
Gcc : compiler
Arm corss compiler 설치(tool chain) arm-linux-gcc 명령어
리눅스 커널 설치 : make dep, make bzImage -> /ftpboot 로 복사, minicom -> set ip_addr, tftp zImage kernel, erase, flash kernel(플래쉬 메모리에 커널 퓨징) -> 재부팅
Tftp : udp를 이용하여 파일 전송하는 작고 단순한 프로그램, 임베디드 시스템 개발용으로 사용, apt-get install tftpd tftp
/etc/xinetd.d 폴더에 넣음
Xinetd : 데몬 -> 커널 백그라운드 프로세스, 요청이 도착하면 깨어나 처리, Extended Internet Service Daemon, tcp, udp, rpc 서비스 접근 제어 조절 기능, 서비스 거부 공격 방지, 철저한 로깅
5. porting
Target system을 구성하기 위한 3가지 구성요소
- Boot loader : 하드웨어를 초기화하고 kernel image를 sdram에 올려주어 수행을 넘겨주는 역할을 하는 프로그램
- Os kernel : os의 핵심 프로그램
- Root file system : kernel에서 사용할 file system
Optional : user file system : utility나 data file등을 위해 추가적으로 사용할 file system
Boot loader : 시스템이 부팅될 때 가장 먼저 실행되는 프로그램, hardware initialization(cpu clock, memory timing, interrupt, uart, pc의 bios), kernel load(운영체제를 ram에 올려주고 실행), download image to sdram, fusing flash rom
Start.s -> c_main() -> bootkernel() or run command()
Kernel : OS의 핵심기능을 수행하는 프로그램
- Process, Memory, Device, Network, File System Management
kernel image : kernel을 압축한 것으로 bootloader에 의해 압축 해제되어 sdram으로 load된다.
시스템의 저장 공간을 최소한으로 사용하기 위한 목적으로 flash memory에 압축된 상태로 존재
Root file system : 리눅스가 동작하기 위해 기본적으로 필요한 프로그램 및 설정파일 존재
kernel에서 기본적인 초기화 작업 후 root file system mount, ramdisk를 이용하여 root file system 구축
ramdisk : ram을 disk처럼 사용하는 것을 ramdisk, 작업 내용을 저장할 수 없다.
User File System : flash file system으로 제작. Flash memory에 file system 구현, 빈번하게 기록과 삭제할 경우 고장 유발
Jffs2 : Journaling Flash File System, 전원이 꺼지더라도 남아있어야 하는 설정파일이나 ramdisk에 포함되지 않은 프로그램등을 저장하기 위해 사용
Target 설정 순서
(jtag)Boot loader fusing -> (serial)download kernel image, file system to sdram etc -> fusing to flash memory
Target operating 순서
Power on -> execute 0 -> load kernel(flash memory -> sdram) -> load(mount) root file system(ramdisk) -> init(/sbin/init) process 실행 (시스템 초기화, 파일시스템 점검, 가상 콘솔 접속 관리) -> login prompt
Boot loader : makefile 생성할 때 linux kernel source 있어야 함, -> make -> blob image 생성 ->
Jtag : pcb와 ic를 테스트하기 위한 목적으로 제정된 표준, 칩 내부에 boundary cell을 두어 외부의 핀과 1:1로 대응시켜 프로세서가 할 수 있는 동작을 중간에 cell을 통해 인위적으로 수행할 수 있어 테스트나 연결 상태 체크.
프로세서의 상태와는 상관없이 디바이스의 모든 외부 핀을 구동시키거나 값을 읽어들일 수 있는 기능 제공.
Target system의 flash memory에 data를 fusing하는 작업을 간편하게 해 주는 프로그램.
Blob image를 cable parallel 0x378 pxa255, detect, flashmem 0 blob 명령어로 fusing
Ramdisk 퓨징 : tftp ramdisk.gz ramdisk -> erase -> flash ramdisk
Meory map 수정 : blob source의 pxa255_pro.h, kernel source의 pxa255_pro.c 수정 -> kernel menu config -> default ramdisk size 설정 -> kernel compile, blob compile -> fusing -> zImage fusing -> ramdisk fusing
6. root file system 제작
Root file system : 리눅스를 구동하기 위해 필요한 파일로 구성된 파일시스템. File system에서 여분의 영역을 체크함으로써 구조적인 상태 검증, 필요한 커널 모듈 로드, 네트워크 초기화, 설정된 디렉토리(/etc/fstab) 마운트, login 프로그램 실행. 리눅스 시스템이 부팅시 필요한 것들을 설정해주고 시스템 운영에 필요한 것들을 초기화 시켜준다.
Linux의 부팅과정
Power -> bios 실행하여 mbr 읽음(커널 시작부분, grub, cpu&memory초기화) -> kernel이 flash memory에서 ram으로 로드 -> kernel은 ramdisk word를 읽어 root file system을 찾아 ramdisk로 load -> root file system image를 ramdisk에 load -> root file system에 있는 init(/etc/inittab) 프로세스 실행(파일시스템 검사 및 연결(fstab), 모듈 적재, 네트워크 서비스 시작) -> getty(login program)
Root file system 필수 설정 파일 : inittab, passwd, shadow, group, rc.d, rc.sysinit, rc, fstab, 유틸리티에서 사용하는 Runtime library
Root file system 제작 : image file 생성(dd) -> image file에 파일 시스템 생성(mke2fs) -> image file mount -> 디렉토리 생성 -> dev -> etc(복사,편집) -> bin, sbin(busybox사용 or crosscompile) -> lib -> var(/var/log 생성) -> 이미지 압축(gzip) -> board에 적재
Dd if=/dev/zero of=./ramdisk bs=1024 count=16384 (block size, 파일의 크기)
Mke2fs –m o –N 2000 ramdisk(inode 2000개)
Mount –t ext2 ramdisk ./ram_point-o loop (파일 하나를 디바이스처럼 취급하도록 loopback device)
Cp –dpR (uid, gid, 권한, 시간정보, 하위폴더 그대로 복사)
Busybox : 리눅스의 여러가지 명령과 utility 포함, ./busybox ls or ln –s busybox ls -> ./ls
7. 커널과 디바이스 드라이버
Kernel programming : kernel core 기능 추가 kernel 알고리즘 개선, kernel 모듈 프로그래밍
Application program : 처음부터 순차적으로 실행
Kernel : system call이나 인터럽트 핸들러를 수행하기 위해 비동기적으로 수행
Library : 모든 library를 link하고 사용할 수 있다. Kernel은 kernel에서 export하는 것들만 사용할 수 있다.
User mode에서는 하드웨어와 메모리에 대한 접근 허용 x
Application program과 kernel program은 서로 다른 메모리 매핑법을 갖고 있으며 프로그램 코드는 서로 다른 address space를 갖고 있다.
Kernel program 은 현재 개발하는 모듈 외에도 커널 전반적으로 함수와 변수의 이름이 충돌하지 않아야 함
/usr/include/linux와 asm 아래에 선언된 헤더파일 만을 include 한다
Kernel 에러코드 검사하고 처리해야함. Stack의 크기가 제한되어 있으므로 큰 배열을 사용하거나 recursion 많이 일어나지 않도록 주의. Application과 데이터를 주고 받기 위해 특별한 함수 사용, 실수, mmx 사용 x
Inb, inw, inl, outb, outw, outl : port에서 1byte, 2byte, 4byte를 읽고 쓴다.
Insb, insw, insl, outsb, outsw, outsl : memory의 addr부터 count*byte를 읽어서 port에 읽고 쓴다
입출력이 너무 빠르면 device에서 처리할 수 없을 수도 있으므로 _p를 붙이면 잠시 멈춘다.
cli()/sti() = clear/set interrupt enable
save_flags()/restore_flags() = status register의 내용을 저장하고 복원. 같은 함수 안에서 호출되어야 함
request_irq()/free_irq() = 커널로부터 irq요청, irq 반납
kmalloc() = 물리적으로 연속적인 메모리 할당, kfree(), vmalloc() = 크기 제한 없음, 가상 주소 공간에서 연속적인 메모리 할당, vmfree()
copy_from_user() = 사용자 주소공간에서 복사, copy_to_user(), memset(), put_user(), get_user() = 사용자 공간에 datum을 전달하거나 가져옴
sleep_on() = uninterrubtible, sleep_on_interuptible(), wake_up, wake_up_interruptible()
register_xxxdev() = device driver 등록, unregister_xxxdev(), register_netdev, unregister_netdev, major(), minor()
system call : user mode process는 kernel영역에 접근할 수 없으므로 서로 간의 interface(communication channel), 소프트웨어 인터럽트를 통해 커널에 서비스 요청, posix api를 준수하는 library함수 안에서 system call 호출
posix api : 표준 운영체제 인터페이스, application이 시스템에 각 서비스를 요청할 때 어떠한 함수를 사용할 지 지정한 것
응용프로그램 -> open()(posix api) -> sys_open()(system call)
System call 추가
Kernel 수정 : system call 번호 할당(uinstd.h) -> system call 호출 테이블 등록(entry-common.S, calls.S) -> system call 함수 구현(test_syscall.c, calls.S의 함수 이름과 같아야 함) ->kernel compile 및 board에 적재 -> userApplication(unistd.h의 함수 이름과 같아야 함)
Arm-linux-gcc –I –-c –o /root/newsys.o newsys.c -> ar명령어로 라이브러리 만들고 ranlib으로 라이브러리 색인
Arm-linux-gcc –o app_test_syscall app_test_syscall.c –L/root –lnew (new라는 이름의 라이브러리와 링크)
Linux의 system call은 interrupt 처리 메커니즘 사용
Interrupt : 주변장치와 커널이 통신하는 방식으로 장치가 자신에게 발생한 비동기적 사건을 kernel에게 알림
Device Driver : 물리적인 hardware장치를 다루고 관리하는 software, user application이 driver에게 요청하면 driver는 hardware를 구동시켜 목적 달성, major, minor number, device와 system memory같에 data 전달 담당하는 kernel 내부기능. Device <-> Device Driver <-> System Memory
Char driver : device를 파일처럼 취급하고 직접 read/write 수행. Data는 stream 방식으로 전송. Console, keyboard, serial port driver 등. Register_chrdev()
Block driver : disk와 같이 file system을 기반으로 일정한 block단위로 data read/write 수행. Floppy disk, hard disk, cdrom. Register_blkdev()
Network driver : network의 physical layer와 frame단위의 데이터를 송수신. Eth. Register_netdev()
Insmod -> module_init() -> register_chrdev() 호출함, rmmod -> module_exit() -> unregister_chrdev() 호출함
Insmod : module을 kernel에 적재
User application 에서 open() 함수로 driver 호출하면 device_open() 함수 호출 <-> device_release()
MOD_INC_USE_COUNT
User application : open(/dev/testdd) 하면 mknod를 통하여 /dev에 만들어진 node를 open
User program의 open, close, read, write함수가 system call을 통해 device driver의 device_open, device_close등의 파일연산구조체에 포함된 함수 호출.
Major number : 커널에서 디바이스 드라이버를 구분하는데 사용
Minor number : 디바이스 드라이버에서 필요한 경우 장치를 구분하기 위해 사용
I_node의 i_rdev에 상위 8비트는 major, 하위8비트는 minor number로 구성
Mknod로 디바이스 드라이버에 접근할 수 있는 장치파일 생성
Mknod testdd c 252 0 (character, major, minor)
Major_inode->i_rdev) -> major번호 얻음
Insmod = module을 설치, rmmod = module을 제거, lsmod = load된 module 정보 표시
8. 커널모듈프로그래밍
Driver <–> Controller <-> Device
디바이스 = controller + device
Controller : driver와 device간의 interface, 제어레지스터, 상태레지스터, 내부버퍼로 구성
드라이버에서 제어기 접근 방식
: memory mapped io : 제어 레지스터가 메모리 주소와 연관. 메모리 read/write 연산을 통해 제어 레지스터접근
: special in/out instruction : in, out명령을 이용하여 레지스터의 값을 얻어옴
장치에서 드라이버에 결과를 알려주는 방식
: polling : 드라이버가 계속해서 controller를 관찰
: interrupt : 수행이 끝나면 device가 driver에게 결과를 알려줌
Character device : 파일 시스템에 노드 형태로 존재, 순차적인 접근만 허용
Block device : 파일 시스템에 노드 형태로 존재, 버퍼를 이용하여 파일시스템 구축 가능, 블록 단위의 데이터이동
Network device : 특별한 인터페이스 사용, packet단위의 접근
디바이스파일 : 디바이스 드라이버를 접근하는 통로, 장치파일의 inode는 type, major, minor number로 구성
디바이스 파일의 생성 : mknod
하드웨어와 운영체제의 데이터 전달은 하나의 공통된 인터페이스(파일연산) 형태로 추상 데이터 타입
모놀리식 커널 : 모든 기능을 커널 내부에 구현, 사소한 변경에도 커널 컴파일과 리부팅 필요, 커널 크기가 커짐, 거의 사용되지 않는 기능이 메모리에 상주
모듈 프로그래밍 : 마이크로 커널로 향하는 단계, 커널의 일부기능을 커널에서 제외하여 모듈로 구현, 작고 깔끔한 커널, 메모리의 효율적 이용, 기능이 필요할 때만 메모리에 적재
모듈 프로그래밍의 대상 : 파일시스템, 디바이스 드라이버, 하드웨어 종속적인 부분과 초기화 부분을 제외하고는 거의 모든 커널 기능을 모듈화 가능
모듈 인터페이스 종류 : register_filesyste, unregister_filesystem, read_super, put_super, register_chrdev, open etc
Level3(응용프로그램) ~ level0(kernel module) : 보호모드 -> 프로그램이 사용할 수 있는 자원에 한계를 두어 시스템 파괴 방지, 효율적인 자원 통제
병행처리 : 커널 모듈은 비동기적으로 실행되는 이벤트 처리 프로그램의 형태, 하나의 thread에서 실행되므로 여러 작업들을 잘 짜맞추어야함, 선점으로 인한 문맥교환 발생할 수 없음
Insmod module_name.o , rmmod module_name
모듈을 위한 system call
Create_module : 모듈을 위한 메모리 할당, module_list에 새로운 엔트리 할당
Init_module : 모듈을 디스크에서 할당한 메모리 공간에 적재, 커널 내부 심볼 연결, 모듈 내의 init_module 함수 호출
Delete_module : init_module과 반대
Get_kernel_syms : 커널의 심볼을 얻을 때 사용
Module_init () : 모듈이 커널에 적재될 때 , module_exit() : 모듈이 커널에서 제거될 때
Ctrl+alt +f1 = 콘솔모드 f7 = 콘솔모드 해제
모듈프로그래밍 시 예외처리 잘해야함, 실수, mmx 연산 사용 x, 가능하면 동적할당, recursion 금지, 다른 platform과 호환 가능한 프로그래밍
/proc : 커널이나 모듈이 사용자 프로세스 혹은 사용자에게 정보를 제공하거나, 사용자가 커널의 여러 옵션을 설정할 수 있는 방법을 제공하는 특별한 파일 시스템. 사용자와 커널 간의 인터페이스로 사용 가능
/proc/cpuinfo, /proc/devices
Create_proc_entry : /proc 파일 등록
Remove_proc_entry : /proc 파일 제거
Read_proc_t, write_proc_t : proc_dir_entry의 read_proc, write_proc에 연결, -> page_size이내의 입출력
파일연산핸들러 구현 후 proc_fops와 연결 -> 데이터 크기에 제한 없음
Insmod proc_fs.ko -> proc디렉토리에 새로운 파일 생성
Device open()
1. 디바이스에 관련된 error들을 살펴본다
2. 디바이스의 초기화 작업을 수행한다
3. Minor number를 살펴보고 필요하다면 f_op pointer값을 수정한다
4. Filp->private_area가 가리키는 데이터를 할당하고 초기화 한다
5. Usage count(모듈을 사용하고 있는 프로세스 개수)를 증가시킨다.
MOD_INC_USE_COUNT, MOD_DEC_USE_COUNT, MOD_IN_USE(usage count 0인지 검사)
Release() : flip->private_data()영역에 있는 데이터 반환, usage count 감소
Read(), write() : 커널 주소 공간과 사용자 주소 공간의 데이터 이동
Copy_from_user(), copy_to_user(), get_user(), put_user() 단위 크기는 포인터 타입에 따라 결정됨, datum에저장
Driver의 buffer에서 copy_to_user하면 application 의 buffer에 copy됨
Rmmod ker_buf
Rm /dev/ker_buf
Ioctl : 읽기, 쓰기 이외의 부가적인 연산을 위한 인터페이스(io control)
Ioctl 명령번호 : type 8bit magic number + number 8bit 순서대로 주는 기본 번호 + direction 응용프로그램 입장에서 본 데이터 이동 방향 + size 8~14 bit 이동되는 데이터 크기
Io : 데이터 이동이 없는 ioctl
Ior : 커널에서 응용, iow : 응용에서 커널, iowr : 양방향
Ioc_dir : 데이터 이동 방향, ioc_type : magic number, ioc_nr : 기본번호 , ioc_size : 데이터 이동 크기
9. huins 보드 디바이스 드라이버 실습
application실행할 때 주의할 점은 blocking 방식을 사용하여야 한다.
GPIO82, GPIO83이 LED0,1과 연결
GPIO는 General-purpose io ports의 의미로 일반적인 목적으로 입출력하는 포트를 뜻함. 84개의 gpio포트
GPLR : GPIO핀이 입력모드일 때 현재 입력상태값을 표시. 1이면 입력이 HIGH
GPSR, GPCR : HIGH, LOW로 설정, 둘 다 0을 입력하면 아무 영향이 없음
GPDR : 1이면 출력, 0이면 입력
GRER, GFER : 상승, 하강 에지를 감시하여 발생하면 값이 1이 된다.
GEDR : GPIO핀이 입력이고 GRER이나 GFER이 SET되어 있으면 에지가 발생했을 때 GEDR의 필드가 1이 된다. CLEAR하려면 해당 비트에 1써준다.
GAFR_L, GAFR_U : GPIO핀을 특정 기능을 위한 핀으로 사용할 지 GPIO핀으로 쓸 것인지 결정, 1이면 특정 기능
Major number = inode->i_rdev>>8, minor number = inode->i_rdev&&0xFF
3번째 레지스터의 18번 19번 비트가 led와 연결되어 있으므로 gpdr2_address |= (1<<18) 하면 led0 세팅
User application에서는 open(/dev/gpio) 해서 node를 통하여 driver에 접근
'UNIX' 카테고리의 다른 글
라즈베리파이 시간 설정 (0) | 2014.05.16 |
---|---|
php pear 설치 (0) | 2014.05.12 |
리눅스 현재시간 동기화 (0) | 2014.04.20 |
리눅스 crontab 크론 (0) | 2014.03.25 |
iptable (0) | 2014.03.19 |