SMALL
부트로더에서 printenv해서 그냥 보통 수정할만한 내용은 initrd 가 가장 바뀔 가능성이 높음
메인 메모리 그리고 접근하도록 하자.
추천 참고 레퍼 사이트
: embedded crazy boy
ioctl —> 제어 데이터를 핸들링
write —> 실질적인 데이터를 핸들링
디바이스 드라이버의 데이터
제어 데이터
실질적인 데이터
ioctl 구성
32bit로 구성
[2] [ 14(데이터 크기) ] [ 8 (매직넘버) ] [ 8(구분번호) ]
매직넘버 : 아스키값도 가능 사이즈만 넘지 않자
cmd 명령의 해석 매크로 함수
_IOC_NR : 구분 번호 필드 값을 읽는 매크로
_IOC_TYPE : 매직 넘버 필드값을 읽는 매크로
_IOC_SIZE : 데이터의 크기 필드값을 읽는 매크로
_IOC_DIR : 읽기와 쓰기 속성 필드값을 읽는 매크로
cmd 명령의 작성 매크로 함수
_IO : 부가적인 데이터가 없는 명령을 만드는 매크로
_IOR : 데이터를 읽어오기 위한 명령을 작성
_IOW : 데이터를 써 넣기 위한 명령을 작성
_IOWR : 디바이스 드라이버에서 읽고 쓰기위한 명령을 작성하는 매크로
ioctl을 이용해서 디바이스 드라이버에 명려을 내리니까, rootkit 만들 때,특정 루틴을 등록하면 된다.
Kernel Timer
폴링에 가깝다.
타이밍 하드웨어가 일정한 간격으로 생성하는 인터럽트로, 시스템 시작 시 커널이 HZ에 설정하는 값이다.
아키텍쳐마다 다르면 아키택쳐의 param.h 에 정의되어 있음
jiffies : 초당 HZ 값 만큼 증가하는 전역 변수
jiffies_64 : 초당 HZ 값 만큼 증가하는 전역 변수 64 bit
HZ : 1 초 당 발생되는 타이머 인터럽트 횟수
get_jiffies_64() : jiffies_64 를 참조하기 위한 함수
리눅스에서 인터럽트 처리해주는 함수
하드웨어 인터럽트 처리 루틴, 벡터 테이블의 함수 포인터 느낌
do_IRQ(n) 함수를 사용 한다. Interrupt 백터임.
jiffies 는 <linux/jiffies.h> 에 선언되어 있음
1 초에 HZ개의 지피가 있으므로, 초를 지피로 변환하려면,
seconds * HZ
마찬가지로 지피를 초로 변환 하려면,
jiffies / HZ
<code>
j = jiffies; /*1초*/
stamp_1 = j + HZ /*현재로부터 1초*/
stamp_hald = j + HZ/2 /*1/2초*/
짧은 지연 처리 함수
mdelay()
udelay()
ndelay()
커널 타이머 응용
현재 프로세를 차단[블럭]을 하지 않으면서도 나중에 수행할 작업을 스케줄링 할 수 있다.
커널 타이머는 클록 틱 단위로 함수 실행을 미래 특정 시간으로 지연시킬 수 있따.
struct timer_list : 커널 타이머 구조체
init_timer : 커널 타이머 구조체를 초기화 함수
add_timer : 커널 타이머에 수행될 함수를 등록
del_timer : 커널 타이머 목록에서 등록된 것을 제거
인터럽트의 처리를 두 단계로 분리
톱 하프
인터럽트 핸들러
인터럽트가 발생하는 즉시 실행되는 타임 크리티컬한 작업들
인터럽트인데 처리할 코드가 간단하면 톱 하프
바톰 하프
나중에 해도 무관한 작업들
모든 인터럽트를 활성화시킨 상태에서 실행
(보통 인터럽트 핸들러가 리던 되면 실행)
인터럽트인데 너무 처리할 코드가 많으면 바톰 하프를 사용
do_IRQ(n) —> 등록된 irq_desc에서 발생된 irq인터럽트 서비스 함수 호출
do_IRQ 공부해보기
보통 위치
include/asm_arm/arch/irqs.h
인터럽트 핸들러에서 메로리 동적 할당
kmalloc(size, GFP_ATOMIC); 사용을 추천함
cat /proc/interrupt에 보면 인터럽트가 등록되어 있음
interrupt 등록하고 만약에 해체할 때는 free_irq 함수를 이용해서 제거해주자.
바톰하프
tasklet, work queue, softirq
softirq : 컴파일 시에 정적으로 생성
tasklet
자신을 스케줄링 한 cpu 상태에서 실행
커널이 선택한 임의의 시각에 실행
태스크릿을 비활성화 시켰다가 나중에 다시 활성화 시킬 수 있음
바톰하프의 경우 다음과 같이 생각하면된다.
탑 하프의 경우, 바로 처리하기 때문에, 이걸 처리한다고 다른것을 처리하지 않는다.
하지만 해당 인터럽트 처리 루틴이 길 경우, 해당 루틴을 수행하면서 다른 인터럽트와 같이 중요한 이벤트를 수행할수 없게 된다.
그래서, 이제 좀 처리 시간이 길거나, 급하지 않은 경우? 여기서 급하지 않다는 것은 주관적인 내용임
그럴 경우, 이제 좀 우선 순위가 낮은 tasklet 과 같은 걸 사용해서 이제 그런 인터럽트 처리를 스케줄링하게 등록해놓는다.
그러면 이제 어떠한 A라는 이벤트가 발생하고 처리하는동안 인터럽트가 발생해도 이제 스케줄링에 등록이 되기 때문에,
하나의 A 이벤트가 종료되고 다음 A 이벤트가 처리되게 된다.
task let 코드 확인
tasklet 특징
자신을 스케줄링 하나 cpu 상에서 실행
커널이 선택한 임의의 시각에 실행
태스크릿을 비활성화 시켰다가 나중에 다시 활성화 시킬 수 있음
태스크릿은 자신을 재 등록할 수 있음
소프트 인터럽트 문맥에서 실행
work queue 코드 확인
워크 큐 구조체를 이용해 등록된 함수의 수행을 keventd와 같은 커널 스레드(워커 스레드)로 수행
커널 선점이 가능한 프로세스 스케줄 방식
등록된 함수가 수행될 때 인터럽트 허용 가능
일반 사용자 프로세스와 같은 태스크의 특성 포함
휴면, 많은 양의 메모리를 할당, 세마포어 획득, 블록 I/O등이 가능
둘 코드의 구성은 거의 똑같다.
LIST
'학부_대학원 > 임베디드 리눅스' 카테고리의 다른 글
tcpdump cross compile (0) | 2019.05.15 |
---|---|
MTD 및 파일시스템 정리 -1 (0) | 2019.05.02 |
(임베디드)리눅스 커널 모듈 - IOCTL (0) | 2017.07.14 |
(임베디드)리눅스 커널 모듈 - 인터럽트, 플랫폼 디바이스 드라이버 (0) | 2017.07.13 |
Platform Device Driver Built In[플랫폼 디바이스 드라이버 빌트인] (0) | 2017.07.13 |