리눅스 & 안드로이드2011. 2. 15. 16:18
Kernel Command Line은 linux kernel이 시작되면서 출력되는 메시지 이다.

<5>Kernel command line: qemu=1 console=ttyS0 android.checkjni=1 android.qemud=ttyS1 ndns=3
in case of Android emulator(Goldfish)

이 command line은 .config 파일에 명시되어 있고, 결국 kernel/arch/arm/configs/xxxx_defconfig를 참조/수정하면 된다.

<활용 예제>
 kernel/init/main.c 소스파일의 *_initcall에 대한 debugging message를 확인하기 위해서는 initcall_debug라는 parameter가 추가되어 있어야 하는데, 이것을 kernel command line에 추가할 수 있다.
 즉, CONFIG_CMDLINE= \
         "qemu=1 console=ttyS0 android.checkjni=1 android.qemud=ttyS1 ndns=3 initcall_debug=1"
 이렇게 추가하면 된다.

Posted by 세월의돌
리눅스 & 안드로이드2011. 2. 11. 17:03
  • __attribute__((__used__))
    • 컴파일러가 코드를 최적화 할 때, 사용되지 않은 변수라 하더라도 제거하지 않도록 한다
    • "unused variable" 관련 compile warning을 방지
  • __attribute__((__aligned__(x)))
    • 변수가 위치하는 메모리의 주소를 x의 배수로 정렬한다
    • e.g) __attribute__((__aligned__(sizeof(long))))
  • __attribute__((__packed__))
    • 구조체 변수에대한 메모리를 할당 할 때, 기본적인 align 규칙(보통은 word, 4 bytes)을 따르지 않고, 실제 데이터의 크기 만큼만 메모리를 할당 하도록 한다
  • __attribute__((__section__(x)))
    • 변수가 ELF 오브젝트 내부에 x라는 이름을 갖는 특별한 섹션 안에 만들어지도록 한다
    • 주로 kernel 초기화 시에만 필요한 코드들을 .init.xxx section에 위치시키고, 사용 후에는 제거(free)하여 가용 메모리를 늘리는 방법으로 이용된다
    • 또한 이렇게 특정 section에 코드들을 위치시키는 방법은, code의 locality를 높여 instruction cache의 hit rate가 높아질 가능성(pipeline broken rate가 낮아질 가능성)이 있다
    • e.g.) __attribute__((__section__(".init.setup")))

# Practical Example #
(kernel/include/linux/init.h)
/*
 * Only for really core code.  See moduleparam.h for the normal way.
 *
 * Force the alignment so the compiler doesn't space elements of the
 * obs_kernel_param "array" too far apart in .init.setup.
 */
#define __setup_param(str, unique_id, fn, early) \
static const char __setup_str_##unique_id[] __initconst \
__attribute__((__aligned__(1))) = str; \
static struct obs_kernel_param __setup_##unique_id \
__attribute__((__used__)) \
                __attribute__((__section__(.init.setup))) \
__attribute__((aligned((sizeof(long))))) \
= { __setup_str_##unique_id, fn, early }

#define __setup(str, fn) \
__setup_param(str, fn, fn, 0)


Posted by 세월의돌
리눅스 & 안드로이드2011. 2. 11. 13:28
각각 Bootstrap loader와 Kernel vmlinux의 head.o(head.S) 두 개의 소스파일은 별개이며 혼돈해서는 안된다.

* Bootloader
  • 전원이 처음 인가되면 곧바로 실행되는 시스템의 비휘발성 메모리에 저장되어있는 로우레벨 코드
  • 저수준 초기화를 진행하기 위해 간단한 초기화 코드와 부트 이미지를 로드하기 위한 코드 및 시스템 자체 진단 루틴 등을 포함
  • 최종적으로 OS 이미지를 로드하고 알맞은 곳에 위치시키고나서 제어권을 해당 이미지로 넘긴다
* Bootstrap loader(kernel/arch/arm/boot/compressed/head.S)
  • 커널 이미지의 압축을 해제
  • 커널 이미지를 재배치 하기위한 알맞은 환경을 만든다
  • 커널로 제어권을 옮긴다
* Kernel vmlinux - kernel/arch/arm/kernel/head.S
  • 프로세서와 아키텍처가 올바른지 검사
  • 초기 페이지 테이블 생성
  • 프로세서의 메모리 관리 장치(MMU)를 활성화
    • 예전 기억을 떠올려보면, MMU 활성화 전/후에 TRACE32등의 debugger로 tracing을 하기 위해서는, MMU가 활성화 되기 전에 MMU 활성화 후에 jump될 주소를 미리 계산해서 breakpoint를 설정 해 주어야 함
  • 일부 에러감지 및 리포팅을 위한 설정
  • 커널 본체의 시작점 main.c로 점프
    • MMU의 유/무에 따라서 head-common.S 또는 head-nommu.S에서 start_kernel로 점프할 수도 있다
* Kernel main.o - kernel/init/main.c
  • Kernel command line 처리
  • Call initializing function directly. ex) init_timers() / console_init()
  • *_initcall 매크로를 이용해 초기화 함수들을 ELF 이미지의 특정 section에 등록(do_initcalls에서 호출)
  • do_initcalls()에서 *_initcall을 이용해 등록된 초기화 함수들을 호출한다
  • 초기화 함수와 데이터에 의해 사용된 메모리 영역을 해제 (init_post() in kernel/init/main.c)
    • free_initmem() in kernel/init/main.c
    • ex) .init.text / .init.data / .initcalln.init
  • 시스템 콘솔장치를 연다 (init_post() in kernel/init/main.c)
    • sys_open((const char __user *) "/dev/console", O_RDWR, 0)
  • 최초의 사용자 영역 프로세스를 시작 (init_post() in kernel/init/main.c)
    • run_init_process는 execve() system call을 이용
      • run_init_process(execute_command)
      • run_init_process("/sbin/init")
      • run_init_process("/etc/init")
      • run_init_process("/bin/init");
      • run_init_process("/bin/sh");
    • execve() system call을 이용하므로 실행에 성공하면 return되지 않는다
      • 그러므로 실행에 실패하게 되면, init_post()함수의 마지막에 있는 panic()을 만나 kernel panic이 발생

# cgroup - Control Groups provide a mechanism for aggregating/partitioning sets of tasks, and all their future children, into hierarchical groups with specialized behavior.

'리눅스 & 안드로이드' 카테고리의 다른 글

Kernel Command Line  (0) 2011.02.15
GNU Compiler __attribute__  (2) 2011.02.11
kernel 빌드에서 생성/링크되는 파일들  (0) 2011.02.10
vmlinux image 구성요소  (0) 2011.02.10
Tips for kernel build  (0) 2011.02.09
Posted by 세월의돌
리눅스 & 안드로이드2011. 2. 10. 18:22
<임베디드 리눅스 입문(Embedded Linux Primer, 정보문화사)에서 발췌>


  • vmlinux - ELF 형식의 커널 본체, 심볼, 주석, 디버깅 정보와 아키텍처를 위한 구성 요소들을 포함하고 있다.
  • System.map - vmlinux 모듈에 대한 문자열 방식의 커널 심볼 테이블
  • Image - 심볼과 추가 정보, 주석 등을 제거한 바이너리 형식의 커널 모듈
  • piggy.gz - 위의 Image 파일을 gzip으로 압축한 것.
  • piggy.o - piggy.gz 파일을 어셈블리 언어 형식으로 만들어 둔 것. misc.o와 같이 링크시키기 위해서 변환한 것이다.
  • (bootstrap loader) head.o - ARM 프로세서들을 위해서 공통적으로 사용되는 스타트업 코드. 부트로더가 제어권을 이 모듈에 넘긴다. 여기서의 head.S는 kernel/arch/arm/boot/compressed/head.S이며, kernel/arch/arm/kernel/head.S와 혼돈해서는 안된다!
  • (bootstrap loader) misc.o - 커널 이미지(piggy.gz)의 압축을 풀기 위한 루틴. 몇몇 아키텍처에서 볼 수 있는 친숙한 부팅 메시지인 "Uncompressing Linux ... Done"을 이 모듈이 출력한다. (오호?!)
  • vmlinux - 복합적인 커널 이미지. 이름 선택이 그리 좋지는 않은데, 커널 본체와 이름이 같기 때문이다. 커널 본체(kernel proper)와 복합 이미지는 이름은 같지만 다른 파일이다. 이 바이너리 이미지는 커널 본체가 이 표에 있는 다른 오브젝트들과 링크된 결과물이다.
  • zImage - 부트로더에 의해서 로드될 최종적인 복합 커널 이미지 파일.

 + vmlinux > objcopy > image > gzip > piggy.gz > asm > piggy.o, misc.o, head.o > ld > vmlinux(zImage)
    

'리눅스 & 안드로이드' 카테고리의 다른 글

GNU Compiler __attribute__  (2) 2011.02.11
Embedded Linux on ARM 부팅 과정  (0) 2011.02.11
vmlinux image 구성요소  (0) 2011.02.10
Tips for kernel build  (0) 2011.02.09
[퍼온글] MTD Partition  (0) 2011.02.07
Posted by 세월의돌
리눅스 & 안드로이드2011. 2. 10. 18:17
<임베디드 리눅스 입문(Embedded Linux Primer, 정보문화사)에서 발췌>



Posted by 세월의돌
* (Android) Kernel 빌드 명령어:
(1) # make mrproper
(2) # make distclean
(3) # make *_defconfig ARCH=arm
(4) # make ARCH=arm CROSS_COMPILE=arm-eabi-
>>> (4)의 명령에 V=1 옵션을 추가하면, 빌드 중 자세한 출력 메세지를 볼 수 있다.
>>> 위의 내용들은 # make ARCH=arm help 명령어를 입력하면 친절하게 출력되는 내용이었다. help를 확인할 때도, ARCH(아키텍쳐)를 명시하는게 중요!
>>> 어떤 경우에는 환경변수가 필요할 수 도 있다;; e.g.) # export TARGET_PRODUCT=product_name


* 각 kernel source directory에 존재하는 Kconfig 파일들의 내용에 따라 configuration menu 항목들이 결정되는데, 이때 xxx_defconfig 등 기본 설정값에의해 정의되지 않는 구성에 대해서는 .config를 생성할 때 사용자에게 설정을 요구하게 되는것 같다. -> 이래서 새로운 모듈을 추가하고, xxx_defconfig에 추가하지 않아, 물어보는 현상이 발생했던 것이구나;;

Posted by 세월의돌

안드로이드와 같은 임베디드 시스템에서 플래시 메모리를 리눅스의 루트 파일 시스템으로 사용하기 위해서 'MTD(Memory Technology Device) 블럭 디바이스 드라이버'라는 것을 사용합니다.

HTC 기반 안드로이드폰의 기본 MTD 파티션은 아래와 같습니다. (기기에 따라 차이가 있을 수 있습니다)

MISC - CID를 포함한 변수 항목과 특성을 기록한 파티션
RECOVERY - OS의 백업이나 업그레이드 등의 기능을 사용자가 이용할 수 있는 리커버리가 설치되는 파티션
BOOT - OS의 커널과 램디스크가 설치되는 공간으로, 커널은 OS의 가장 핵심적인 부분으로 자원(메모리, 프로세스)을 효율적으로 관리하고 시스템을 제어하는 역할을 합니다.
SYSTEM - OS의 가장 기본적이고 필수적인 소프트웨어가 설치되는 공간으로 시스템의 중요한 부분이기 때문에 일반적으로 쓰기 방지(write protection)가 설정되어 있습니다.
CACHE - 임시파일들이 저장되는 공간으로 실제 기기 사용시에는 영향을 주지 않습니다.
DATA - 실제 사용자의 데이터가 저장되는 공간입니다. 다운받아 설치한 어플이라던가 셋팅 정보, 받은 메시지 등의 사용 중인 데이터가 기록됩니다.

(기본적으로 안드로이드의 플래시 메모리 파일시스템 포맷은 yaffs2를 사용합니다)

실제로 그러한가 확인 해 봅시다!!!

adb shell이나 terminal emulator에서 cat /proc/mtd 명령을 입력하면 아래와 같은 결과값을 확인할 수 있습니다.

mtd0: 00040000 00020000 "misc"
mtd1: 00500000 00020000 "recovery"
mtd2: 00280000 00020000 "boot"
mtd3: 04380000 00020000 "system"
mtd4: 04380000 00020000 "cache"
mtd5: 04ac0000 00020000 "userdata"



'리눅스 & 안드로이드' 카테고리의 다른 글

vmlinux image 구성요소  (0) 2011.02.10
Tips for kernel build  (0) 2011.02.09
fcntl function in the start_property_service()  (0) 2011.02.07
Android Self Q&A (업데이트 중...)  (0) 2011.02.07
Redirect stderr to stdout  (0) 2011.01.31
Posted by 세월의돌
fcntl 시스템호출은 이미 열려있는 파일의 특성 제어를 위해서 사용된다.

* fcntl(fd, F_SETFD, FD_CLOEXEC);
>> exec 등으로 process를 실행하면, 기존 process를 대치하게 되는데, 이 때 다른 설정이 없으면 기본적으로 기존에 열려있던 file descriptor는 열려있던 상태로 새로운 process로 상속된다.(open-on-exec, /proc/pid/fd에서 확인가능) 이를 방지하기 위해, FD_CLOEXEC를 지정하면(close-on-exec) exec로 기존 process가 대치될 경우, 지정된 file descriptor는 닫히게 된다.

* fcntl(fd, F_SETFL, O_NONBLOCK);
>> 기본적으로 입력(Input)은 block 모드(예를들면 STDIN으로 입력을 기다리게되면, 입력이 완료될 때까지 명령어 수행이 이루어 지지 않고 대기한다)로 동작하게 되는데, O_NONBLOCK을 설정하게 되면, 입력(또는 읽을 데이터)이 없을 경우 바로 -1을 반환한다.

'리눅스 & 안드로이드' 카테고리의 다른 글

Tips for kernel build  (0) 2011.02.09
[퍼온글] MTD Partition  (0) 2011.02.07
Android Self Q&A (업데이트 중...)  (0) 2011.02.07
Redirect stderr to stdout  (0) 2011.01.31
Android Gingerbread Porting 작업일지  (0) 2011.01.31
Posted by 세월의돌
Q1) system/core/init/init.c의 main()에 보면, /dev, /dev/pts, /proc, /sys 등의 디렉토리를 생성하고 마운트하는데, 마운트 대상이 되는 실제 (물리적인) directory는 어디에서 오는가? (kernel이 부팅되면 filesystem을 구성하는 과정을 알고 싶은것?)
A)

Q2) /proc/cmdline, /proc/cpuinfo 등은 언제, 누가 생성하는가? 내용은 어디로부터 가져오는가? 기 입력된 고정된 데이터?
A)

Q3) system/core/init/init.c의 main()에서, property_set() 함수를 이용하여 몇몇 프로퍼티를 초기화하는 부분이 있는데, "부트로더로부터 커널로 전달된 부팅옵션의 내용"을 분석 import_kernel_nv() 해서 ro.factorytest ro.serialno ro.bootmode등을 초기화 한다. "부트로더로부터 커널로 전달"은 어떻게 이루어 지는가?
A)

Q4) SIGCHLD signal handling을 위해 socketpair() 함수를 통해 생성되는 2개의 socket을 이용하는 이유는?
(하나는 sigchld_handler에서 사용하고 다른 하나는 이벤트 핸들러(?)에서 사용된다.)
[참고] socketpair() 함수는 소켓 쌍을 생성한다. 생성된 소켓 쌍은 서로 구별할 수 없다. 보통 부모 자식 프로세스간 내부 통신(IPC)를 위해서 사용한다.
A)

Q5) dmesg를 이용하여 kmsg를 확인해 보면, start_kernel() 함수에서 출력하는 printk msg도 출력된다. stdout을 /dev/kmsg로 redirection하는 코드는 init process에서 실행되는데, 어떻게 그 전에 실행되는 start_kernel()의 printk msg도 보일까? /dev/kmsg로 redirection 되기 이전의 stdout도 buffering 되어 있다는 의미인가?
A)

Q6) 왜 android root file system image에는 "/dev" directory가 존재하지 않는가?
A)

Q7) android에서 사용하는 property service는 각 property 별로 사용자권한을 uid로 관리한다. "실제 구현하려는 시스템이 동작 중에 프로퍼티 설정을 변경할 필요가 있다면 각 프로퍼티에 대한 접근 권한을 고려하여 구현해야 한다"라고 되어 있는데, 어떤 프로세스에서 특정 property를 수정해야 할 필요성이 있다면, 어떻게 해당 프로세스를 특정(필요한) uid로 실행할 수 있는가? application level에서도 가능한 것인가?
A)

Q8) 위 Q7에 추가적으로, 만약 다른 uid를 필요로하는 property를 변경할 필요성이 있는 경우에는 어떻게 dynamic하게 uid를 변경하여 해당 property를 변경할 것인가?
A)

Q)
A)

Q)
A)

Posted by 세월의돌
리눅스 & 안드로이드2011. 1. 31. 15:03
Linux에서 명령어를 실행하고, 실행결과나 에러를 확인하기 위해 화면 출력을 확인하게 되는데,
눈에 보이는 화면은 둘 이지만, 실제로는 stderr과 stdout으로 나뉘어져 있다.

학부시절 과제를 하면서 stderr과 stdout의 존재에 대해서는 익히 알고 있었지만,
실제 shell에서 redirect를 하는 방법은 모르고 있었는데, 둘로 나누어진 출력을 그대로 사용하면
log를 파일로 redirect해서 보려고 하거나 pipeline을 통해 다른 명령어와 조합하려 할 때 여간 불편한게 아니다.

Redirect 방법:

(1) Redirect stderr to stdout - 아래와 같이 하면 우리눈에 보이는것에는 차이가 없다.

# cmd 2>&1


(2) Redirect stderr & stdout to file - 단순히 (1)의 결과를 파일로 redirect하면 될거라 생각했는데, 그 반대 임.

# cmd > output-file 2>&1

Posted by 세월의돌