커널에 관련해서 소스를 뒤지거나 Kernel Tree 안의 Documents들을 참조하는 일이 잦아졌다. 내 피씨(의 하드디스크)가 매우 느린 관계로 I/O 부하를 좀 줄이고자 웹사이트를 자주 뒤지는 편이다. 다음 두 개가 좀 편하다. 다른 건 나중에 추가!
Kernel Source : http://lxr.linux.no
Kernel Documents : http://www.mjmwired.net/kernel/Documentation/
커널에 관련해서 소스를 뒤지거나 Kernel Tree 안의 Documents들을 참조하는 일이 잦아졌다. 내 피씨(의 하드디스크)가 매우 느린 관계로 I/O 부하를 좀 줄이고자 웹사이트를 자주 뒤지는 편이다. 다음 두 개가 좀 편하다. 다른 건 나중에 추가!
Kernel Source : http://lxr.linux.no
Kernel Documents : http://www.mjmwired.net/kernel/Documentation/
Linux Device Driver 중 Character device 의 코드를 보면 기존의 2.6 기준으로 수정되지 않은 코드들은 register_chrdrv() 함수를 사용하여 Character device를 등록하도록 되어 있다. register_chrdrv 함수의 원형은 다음과 같다.
int register_chrdev(unsigned int major, const char *name,
const struct file_operations *fops)
그러나 2.6의 디바이스 드라이버들은 이와 다른 방식을 사용한다. register_chrdrv를 사용하는 방식은 Linux device driver 개정 3판을 보면 3장의 “예전 방식”이라는 부분에서 이를 다룬다. 예전 방식이 아닌 새로운 방식으로 작성하려면 register_chrdev 대신 register_chrdrv_region/alloc_chrdev_region 과 cdev_init, cdev_add 로 작성하면 된다.
register_chrdrv_region 함수는 원하는 디바이스의 번호를 미리 알고 있을 때 사용하고, alloc_chrdev_region 함수는 디바이스의 번호를 동적으로 할당받아 파라미터로 받는 dev_t 구조체 포인터를 이용해 dev_t 구조체에 넣는다.
register_chrdrv 대신 register_chrdrv_region을 사용하는 것으로 혼동할 수 있는데 그게 아닌 cdev_add 함수까지 사용하여야 한다. 실제 커널 소스의 register_chrdrv 함수를 보면 이런 과정이 구현되어 있음을 볼 수 있다.
cdev_add 함수를 사용하기 위해서는 struct cdev 구조체를 사용하여야 하는데 이 구조체를 초기화 시켜주는 함수가 cdev_init 이다. struct cdev 구조체 등을 사용하려면 <linux/cdev.h> 를 include하여야 한다. 다음은 사용 예이다.
…
Linux Kernel의 프로세스 상태 변경 매크로(set_task_state, set_current_state)를 살펴보다가 ARM 아키텍처에서 다음과 같이 구현된 것을 보았다.
#define set_task_state(tsk, state_value) \
set_mb((tsk)->state, (state_value))
#define set_current_state(state_value) \
set_mb(current->state, (state_value))
set_mb 매크로는 시스템마다 다르게 구현되어 있는데 ARM 쪽을 따라가보면 다음과 같이 쓰여져 있다.
#define dmb() __asm__ __volatile__ (“” : : : “memory”)
#define smp_mb() dmb()
#define set_mb(var, value) do { var = value; smp_mb(); } while (0)
do-while-0 구문에 대해서는 이 글을 참고하도록 하고, memory barrier에 대해서는 이 글을 참고하라. dmb() 의 inline assembly의 구조와 설명은 이 글을 참고하자.
참고된 글을 정리하자면, 명령이 R, W, R, W, R, W 순으로 사용된다면, 이를 하드웨어 혹은 소프트웨어 적으로 R, R, R, W, W, W 순으로 배열하는 등의 최적화를 할 수 있는데, 이 때 명령의 순서를 보장해 주는 역할로써 Memory barrier 라는 것을 구현해서 사용한다. 이는 하드웨어적으로 혹은 소프트웨어적으로 구현되는데 하드웨어적인 방법은 CPU 자체의 명령으로 구현되는 등의 방법이 사용될 수 있고, 소프트웨어적으로 구현될 때 위와 같이 구현될 수 있다.
위 구문은 gcc inline assembly의 확장으로 clobber list에 “memory”를 적어넣어 해당 명령(“” – 아무 명령도 수행하지 않음)을 수행한 후에 변경되는 것이 메모리 타입 저장장치(모든 레지스터, 모든 플래그, 모든 메모리)임을 나타낸다. gcc는 이럴경우 __asm__ __volatile__(“”: : :”memory”) 경계를 넘어가는 최적화 또는 instruction scheduling을 수행하지 않기 때문에 __asm__ __volatile__(“”: : :”memory”)를 사용하면 이전 코드의 수행 완료를 보장할 수 있고 이후 코드가 __asm__ __volatile__(“”: : :”memory”) 이전에 수행되는것을 방지 할수 있다. 별개로 volatile의 경우 읽기 연산에서 메모리에서 한번 읽어온 데이터를 레지스터에 저장해서 사용하는 것이 아닌 사용할 때마다 메모리 참조를 통해 가져오도록 한다.
리눅스 커널 소스를 살펴보다가 헤더쪽의 매크로에서 “do { … } while(0)” 와 같은 것이 많이 쓰인 것을 보았다.
당연히 { … } 이 한번만 실행되고 끝나는 건데, 왜 이렇게 했을까 궁금해서 찾아보았다.
정리하자면,
1. 빈 문장(“;”)은 컴파일러에서 Warning 을 발생시키므로 이를 방지!
2. 지역변수를 할당할 수 있는 Basic block 을 쓸 수 있다.
3. 조건문에서 복잡한 문장을 사용할 수 있다. 예를 들면 다음과 같은 코드가 있다고 했을 때,
4. 3번과 같은 경우에 다음과 같이 사용할 수도 있지 않냐고 생각할 수 있다.
참고 : KLDP의 “의미없는 do while 문“
ARM CPU Now & Future 라는 제목의 무료 동영상이 있길래 한번 보았는데 여러가지 주목할만한-내 주관적으로- 이야기가 있길래 정리한다. 자료 자체는 2008년 11월 25일 자료이므로 현재(2009.9.24) 상황과 비교해서 보는 것도 좋을 듯 하다.
강연 때 사용한 PPT 역시 구글에서 찾을 수 있길래 첨부(링크)한다.
cfile3.uf.1371A41C4ABAD361094B2C.pdf
1. 멀티 코어 관련 개발 기술 필수
일단 ARM 을 버전별로 나누어 정리한 표는 다음과 같다.
ARMv4, v5, v6, v7 별로 어떤 코어가 사용되고 있는지 눈여겨 봐두자. ARM11-MPCore와 Cortex-A9 위에 화살표에 적힌 x1~4는 멀티코어 개수를 나타내는데, 반도체 회사에서 마음대로 최대 4개까지 코어 개수를 조정할 수 있다고 한다. 앞으로 나올 프로세서들에는 기본적으로 MPCore 기술이 들어간다고 하니 멀티코어 관련 개발 기술은 임베디드 개발하에서도 필수적인 기술이 될 듯 하니, 꼭 익혀둘 필요가 있다.
저가형을 대체하고자 하는 Cortex-M3와 Cortex-M1은 안의 FPGA 에 자체 개발한 IP를 탑재하여 시스템에 적용할 수 있다고 한다.
2. 파트너십에 의한 웹 접근성 강화
웹 접근성 향상을 위해서 다양한 소프트웨어 회사들과의 작업중이라고 한다.
1. Adobe Flash player : 자료상으로 2009년 상반기 내에 Adobe Flash player 10가 ARM 기반(ARM v6, ARM v7)으로 출시 될 것이라고 이야기하고 있다.
2. Google Chrome : Google의 웹브라우저인 Chrome 은 PC와 ARM 을 동시에 지원하고 있다고 한다.
3. MS Silverlight & Media codecs : MS 윈도우즈 모바일의 실버라이트 역시 ARM 을 지원하도록 작업중이라고 한다. MS에서 미디어 코덱 역시 ARM을 위해 내어놓고 있다고 하니 멀티미디어 지원에 있어서도 강점을 갖게 될 것이다.
4. Firefox : Firefox 를 ARM CPU에 대해 최적화 작업을 해서 6배 빨라졌다고 한다. 또한, 이에 관현한 작업물들을 오픈소스로 공개하여 ARM 사이트에 가면 공개된 자료를 받아볼 수 있다고 한다. x86 기반의 소스와 비교하면 어떤 최적화 기법을 썼는지 볼 수 있으므로 도움이 되지 않을까?
5. Ubuntu : Canonical 에서 우분투 데스크탑을 ARM v7에서 사용하도록 지원한다고 한다. 단순히 커널 뿐 아니라 오픈 오피스 등의 프로그램 등도 지원한다고 한다. 우분투 기반의 많은 디바이스들이 나올 듯 하다.
위에서 보는 바와 같이 ARM은 임베디드 기기의 Major OS인 윈도우즈, 리눅스를 모두 효과적으로 운영할 수 있도록 지원하고, 플랫폼에 독립적인 웹 환경과 멀티미디어 분야 역시 지원하고 있다. 이를 보면 이미 예측된 바와 같이 무선 환경하의 ARM 기반 디바이스들에 사용될 소프트웨어 및 서비스 시장이 매우 커질 것을 예상할 수 있겠다.
구글 안드로이드 관련 문서들을 살펴보다가 괜찮은 문서가 있으면 공부 및 정리 겸 해서 번역하면서 보려고 생각하다가 그냥 번역하고 인터넷 상에 올리면 안될 것 같아서 문서들 아래에 적혀있는 다음과 같은 문구의 링크된 Content License 부분을 눌러서 보게 되었다.
Except as noted, this content is licensed under Apache 2.0. For details and restrictions, see the Content License.
Android 1.5 r3 – 21 Jul 2009 11:19
Content License 에 따르면, 일단 “Documentaion content”는 Android Open Source Project의 일부로 사용 가능하고, 어떤 코드가 포함된 문서들은 Apache 2.0 라이센스를 따른다고 한다. 물론 그에 앞서 GPLv2나 그 외의 라이센스에 해당하는 소스코드를 포함하는 경우에는 해당 라이센스가 우선된다. Apache 2.0 License에 관해서는 KLDPWiki: 오픈소스 소프트웨어 라이센스 가이드와 Apache 2.0 라이센스 원문, 그리고 Apache 2.0 라이센스의 번역본(김윤수님의 Apache License Version 2.0 번역 완료) 글을 참조해보기 바란다.
그리고 나머지 사이트 상의 다른 모든 자료들은 Creative Commons Attribution 2.5[우리말] 라이센스를 따른다.
RSS 리더로 나는 KLDP Geek forum 을 보곤 한다.
보다보면 재밌는 것들이 많단 말이지.. 글들에 글들을 따라가다보면 몰랐던 혹은 어렴풋이 알았던, 애매한 것들에 대해서 다시한번 생각해보게 되고 알게 된다. 언젠가 적었듯이 이게 KLDP의 묘미가 아닌가 한다.
그 중 하나로 오늘은 cinsk님의 “포인터 이해란 글에 대해.“란 글을 보게 되었다. 글들에 링크되어 있는 글들의 덧글들을 보라.
세상은 넓고, 난 너무 미약하다.
시작은
STDIN 입력은 간단히 <>
입력에서 마지막 \n 없애기
문자열을 나눠서 리스트로 만들기
파일을 쓰기 모드로 열기
그냥은 filename, 추가 쓰기는 >>
파일에 뭘 쓰고 싶을 때는
파일 닫기는
sprintf
printf
찾을 문자열의 시작 인덱스 구하기
시간 구하기
시간 만들기
문자열 연결은 ‘.’ 으로..
환경변수 접근은
ascii <-> character
$ascii_value = ord(“e”); # now 101
$character = chr(101); # now “e”
더 많은 정보는 http://perldoc.perl.org
SET 에서 /P 옵션을 주면 환경변수에 입력값을 넣을 수 있다.
형식은 다음과 같다.
실행 예제
IF 문에서 수식을 사용하고 싶을 때, 예를 들면, 에러 체크를 위해 루프를 도는 개수등을 카운트하고 싶다면 SET 에서 /A 옵션을 사용하고 IF에서 비교 연산자를 사용하면 된다. IF 문의 비교 연산자는 다음과 같다
다음은 start 로 3가지 일을 동시에 처리한 후 goto와 label을 이용, cygwin의 delay로 일정 시간 체크한 후 그 후 에러로 처리하는 bat 파일의 예다.
rem WORK1, 2, 3를 동시에 돌린다. 다음 작업에 dependency 가 있는 작업에
rem start의 /W 옵션을 주어 기다리도록 한다.
start WORK1.bat
start WORK2.bat
start /W WORK3.bat
goto CHECK
:DELAY
rem if LOOP_COUNT >= LOOP_MAX_COUNT
IF %LOOP_COUNT% GEQ %LOOP_MAX_COUNT% (
rem LOOP_COUNT += 1
SET /A LOOP_COUNT+=1
:CHECK
echo Checking…
IF [WORK1 실패조건] (
call WORK4.bat