2017년 8월 30일 수요일

yocto

poky는 빌드시스템 템플릿이다. 빌드는 bitbake를 통해 진행되며 이것은 make와 비슷한 역할을 담당한다. bitbake는 메타데이터라는 빌드설정에 따라 빌드를 수행한다. poky는 재사용되는 이런 빌드설정파일을 모아둔 빌드템플릿으로 보면된다.

poky 다운로드

$ git clone git://git.yoctoproject.org/pok
$ git clone git://git.openembedded.org/meta-openembedded
$ git clone git://code.qt.io/yocto/meta-qt5.git

빌드환경 구성 스크립트

poky 에서 제공되는 스크립트로 빌드환경을 설정한다. 실행시 지정한 빌드디렉토리를 생성하고 bitbake 경로 설정등을 수행한다.
$ cd poky
$ source oe-init-build-env [build-directory]


빌드를 위한 설정파일은 *.conf, *.bb, *.bbclass 세가지가 있다. 이 파일들을 메타데이터라 한다. bitbake는 빌드시 이 세가지 파일을 분석완료 한 후 빌드에 필요한 모든 일을 수행한다.

빌드 환경설정파일

환경설정파일은 *.conf 형식이며, 빌드시 전역적으로 적용된다.

/build/conf/bblayers.conf

“bitbake core-image-minimal “ 과 같이 이미지 빌드 명령을 주면 이 파일을 가장 먼저 파싱한다.
아래처럼 BBLAYERS에 */conf/layer.conf가 있는 디렉토리를 등록한다.
BBLAYERS ?= " poky/meta /poky/meta-poky /meta-qt5 … “

/meta-xx/conf/layer.conf

아래처럼 레시피파일(*.bb, *.bbappend)이 위치를 등록한다. 등록되지 않은 경로의 레시피는 포함되지 않는다.
BBFILES += "${LAYERDIR}/recipes*/*/*.bb ${LAYERDIR}/recipes*/*/*.bbappend"

/meta-xx/conf/machine/machine-name.conf

아래와 같이 보드와 관련된 빌드 변수가 설정된다.

MACHINE_FEATURES = "kernel26 apm alsa ext2 ext3 usbhost ..”
KERNEL_DEVICETREE = "sama5d31ek.dtb …”

/meta-xx/conf/distro/distro-name.conf

기본으로 적용되는 빌드정책을 설정한다.

DISTRO = "poky-atmel"
# Because there is no opengl, some qt packages are empty
ALLOW_EMPTY_qt3d-mkspecs = "1"
...

/build/conf/local.conf
oe-init-build-env 스크립트를 수행하면 local.conf가 자동으로 생성된다. 필요에 따라 이파일을 수정하면 된다.
이 파일을 수정하여 빌드타겟, 크로스컴파일러, CFLAG세팅 등 필요한 빌드설정을 변경할 수 있다.
이 파일을 통해 메타데이터의 설정을 추가하거나 덮어쓸 수 있다.

아래 경로에 등록된 보드이름을 MACHINE변수에 설정한다.
/meta-name/conf/machine/*.conf

아래 경로에 등록된 정책을 DISTRO변수에 설정한다.
/meta-name/conf/distro/*.conf

HOB

hob는 GUI를 통해 local.conf를 설정하고 빌드하여 이미지까지 생성할 수있다.
oe-init-build-env 수행후 hob을 실행하면 직관적인 GUI가 뜬다.

레시피

레시피(*.bb)는 빌드 태스크 단위로 하나의 레시피에서 하나의 패키지가 생성된다고 보면된다.(여러개의 패키지도 가능)
파일형식: <package-name>_<version>.bb
예:  busybox_1.21.1.bb
이 파일에서 소스다운, 패치적용, 의존성 관계, 컴파일, 인스톨 등을 설정한다.
패키지의 형태(RPM, DEB, IPK,TAR)는 build/conf/local.conf 에서 PACKAGE_CLASSES 에 설정한다.

이미지 레시피

이미지 빌드 레시피는 루트파일시스템을 빌드하기위한 레시피로  images디렉토리에 존재한다. find 명령어로 images 디렉토리를 검색하면 빌드가능한 이미지 레시피를 확인할 수 있다.

의존성

특정 레시피를 빌드하기 위해 필요한 것을 말한다.  DEPENDS는 빌드시 필요한 설정을 하고 RDEPENDS는 런타임에 필요한 설정을 한다. 설정값은 PROVIDES이름이다.
ffmpeg_3.1.3.bb의 의존성: DEPENDS = "alsa-lib zlib libogg yasm-native"

PROVIDES는 이름_버젼.bb 에서 레시피 이름이거나 레시피 내부에서 PROVIDES로 직접 설정한 이름이 이다.
예를 들어 ffmpeg의 DEPENDS에 등록된 alsa-lib는 meta/recipes-multimedia/alsa/alsa-lib_1.1.2.bb 에 의존한다.
bitbake는 DEPENDS와 PROVIDES를 분석하여 빌드 순서를 정하게 된다.

PREFERRED_PROVIDER는 PREFERRED_PROVIDER_xxx 형식의 변수로 여러개의 PROVIDE

각종 변수



PR : Package Revision
PN: Package Name
PV: Package Version
P   : Package : "${PN}-${PV}"
PF : Package full name : "${PN}-${PV}-${PR}"
S : Unpacked source code directory - 압축해제, 패치, 컴파일이 진행되는 디렉토리
D: Destination directory: 패키지 설치 디렉토리


각 레시피의 태스크

아래의 명령으로 각 레시피를 통해 수행 가능한 태스크를 확인 할 수 있다.
  > bitbake u-boot -c listtasks
  > bitbake linux-at91 -c listtasks  
  > bitbake core-image-full-cmdline -c listtasks
  > bitbake core-image-full-cmdline -c rootfs : 루트파일시스템만 빌드  




  1. http://www.at91.com/linux4sam/bin/view/Linux4SAM/Sama5d3xekMainPage 빌드 가이드를 따라하다 보면
    QtWayland 에러가 발생할 수도 있다. 관련버그는 최종 에서 해결되었으므로 아래 버젼으로 빌드를 진행해야 한다.
    솔루션: https://codereview.qt-project.org/#/c/187132/
    cd meta-qt5 &&  git checkout -b b5.8 remotes/origin/5.8

    빌드 에러메시지:
| rm -f libQt5WaylandCompositor.so.5.8.0 libQt5WaylandCompositor.so libQt5WaylandCompositor.so.5 libQt5WaylandCompositor.so.5.8
| linking ../../lib/libQt5WaylandCompositor.so.5.8.0
| /usr/src/debug/qtwayland/5.8.0+gitAUTOINC+0e2a950895-r0/git/src/shared/qwaylandxkb.cpp:297: error: undefined reference to 'xkb_keysym_to_utf32'
| /usr/src/debug/qtwayland/5.8.0+gitAUTOINC+0e2a950895-r0/git/src/shared/qwaylandxkb.cpp:337: error: undefined reference to 'xkb_state_mod_name_is_active'
| /usr/src/debug/qtwayland/5.8.0+gitAUTOINC+0e2a950895-r0/git/src/shared/qwaylandxkb.cpp:339: error: undefined reference to 'xkb_state_mod_name_is_active'
| /usr/src/debug/qtwayland/5.8.0+gitAUTOINC+0e2a950895-r0/git/src/shared/qwaylandxkb.cpp:341: error: undefined reference to 'xkb_state_mod_name_is_active'
| /usr/src/debug/qtwayland/5.8.0+gitAUTOINC+0e2a950895-r0/git/src/shared/qwaylandxkb.cpp:343: error: undefined reference to 'xkb_state_mod_name_is_active'



참고:


2017년 7월 4일 화요일

비트레이트로 동영상파일 용량 계산하는 방법

Bit rate단위는 bps(bits per second)로 초당 전송되는 비트의 개수다. 그러므로 계산식은:

용량 = bps * 시간

주의 할점은 bps는 SI단위로 아래처럼 1kbit/s는 1024bps가 아니라는 것이다.
1,000 bit/srate = 1 kbit/s (one kilobit or one thousand bits per second)
1,000,000 bit/srate = 1 Mbit/s (one megabit or one million bits per second)
1,000,000,000 bit/srate = 1 Gbit/s (one gigabit or one billion bits per second)

예를들어 비트레이트가 100kbit/s인 동영상의 길이가 1시간이라면 용량은 아래와 같다.

100,000(100kbit/s) * 3600(1시간) = 360,000,000 bit

byte단위로 고치면 1byte는 8bit이므로 아래처럼 된다.

360,000,000 / 8 = 45000000 B/s (42.9 MiB/s)


참고: 10진수 단위인 kbit/s와 바이너리 단위인 Kibit/s는 아래 처럼 다르다.
Bit rates
NameSymbolMultiple
bit per secondbit/s11
Decimal prefixes (SI)
kilobit per secondkbit/s10310001
megabit per secondMbit/s10610002
gigabit per secondGbit/s10910003
terabit per secondTbit/s101210004
Binary prefixes (IEC 80000-13)
kibibit per secondKibit/s21010241
mebibit per secondMibit/s22010242
gibibit per secondGibit/s23010243
tebibit per second




Coherence vs Consistency

헤깔리는 용어 Coherence와 Consistency의 명쾌한 설명

consistent - the quality of behaving in the same way over time
                standing firm, holding firm
*참조:Shared memory consistency models  F/OSS study

coherent - the quality of being logically connected
              all the parts stick together, hang together
- cache coherent system에서 같은 메모리에 대한 모든 캐쉬는 같은 값을 가진다.
- a multiprocessor is cache consistent if all writes to the same memory location are performed in some sequential order
* 참조: https://en.wikipedia.org/wiki/Cache_coherence

coherent는 하나의 특정영역의 메모리에 관련된 일관성이지만, consistent는 여러 영역의 메모리의 접근에 대한 일관성을 말한다.


2017년 4월 5일 수요일

SE for Android

SE for Android



Security Enhancements for Android™ (SE for Android) 는 안드로이드 보안을 강화하기 위한 구글 프로젝트다.
Android 4.3이전에는 sandbox를 이용했지만 Android 4.3 이후로 SELinux를 적용했고, Android 5.0 부터 완전하게 적용되었다.


  • 보안정책 해제


enforcing : 보안정책에 위반되는 접근은 모두 거부되고, EPERM 에러를 반환한다.
permissive: 보안정잭이 적용되지 않고,  로깅만 된다.


Android 5.0 이후 버젼은 아래 명령으로 AVC 거부 로그를 확인할 수 있다.
adb logcat | grep avc:


enforcing 상태 확인:
adb shell getenforce


enforcing 로 전환
adb shell su 0 setenforce 1


permissive로 전환
adb shell su 0 setenforce 0


영구적으로 해제하려면, bootargs에 androidboot.selinux=permissive를 추가하면 된다.


  • 정책설정
아래명령으로 거부로그를 캡춰한 후 audit2allow를 이용해서 보안정책을 적용할 수 있다.
adb shell su 0 cat /proc/kmsg > dmesg.txt &
audit2allow -p out/target/product/device/root/sepolicy < dmesg.txt


우분투에서 audit2allow를 사용하려면 아래 패키지를 인스톨해야한다.
sudo apt-get install policycoreutils


  • 정책파일 로딩
정책파일은 안드로이드 빌드시 컴파일되고, 램디스크 이미지에 추가된다. 그래서 시스템파티션이 마운트되기전 부팅초기에 로딩된다. 부팅 후에는 정책파일을 /data/security/current에 위치시키고, selinux.reload_policy property를 1로 설정하면 업데이트된다.


  • 정책소스파일 구성
정책설정파일은 external/sepolicy/* 에 위치한다. 이 정책은 안드로이드 플래폼 공통 정책이고 이 파일들은 수정할 필요가 없을 것이다.  각 보드별 정책은 device/vendor/device/BoardConfig.mk 에 BOARD_SEPOLICY* 변수로 설정하고, 정책파일은 device/vendor/device/sepolicy/*에 위치 한다. 여기에 필요한 정책을 추가하면 된다.


정책을 구성하기 위해서는 여러 소스파일이 이용된다.  아래는 주요 안드로이드 정책소스파일이다.
file_contexts : device node, socket, /data directory등 파일 label을 설정
property_contexts: Android properties  위한 label 설정
seapp_contests: 앱 프로세스나 앱 패키지 디렉토리를 위한 label 설정
mac_permissions.xml:  middleware MAC(Mandatory Access Control) 정책 설정, SELinux에 없는 SE for Android 전용파일.
정책규칙은 아래 형식으로 구성된다.


allow  Domains  Types:Classes  Permissions;


Domain : 프로세스 설정을 위한 레이블
Type       : file, socket 같은 오브젝트 설정을 위한 레이블.
Class : 접근한는 오브젝트의 종류
Permission:  적용되는 오퍼레이션


예) allow appdomain app_data_file:file rw_file_perms;
appdomain은  file종류인 app_data_file오브젝트에 rw_fil_perms를 적용한다.


실행 중인 프로세스의 레이블 확인:


# adb shell ps -Z
LABEL                          USER     PID   PPID  NAME
u:r:init:s0                    root      1     0     /init
u:r:kernel:s0                  root      2     0     kthreadd
u:r:kernel:s0                  root      3     2     ksoftirqd/0
u:r:kernel:s0                  root      4     2     kworker/0:0
….
u:r:system_app:s0              system    3582  2471  com.android.settings
u:r:untrusted_app:s0           u0_a16    3605  2471  com.android.voicedialer
u:r:untrusted_app:s0           u0_a22    3627  2471  com.android.calendar
u:r:untrusted_app:s0           u0_a25    3655  2471  com.android.deskclock
u:r:untrusted_app:s0           u0_a28    3684  2471  com.android.email
u:r:untrusted_app:s0           u0_a29    3707  2471  com.android.exchange


  • SPI 장치를 접근하는 JNI를 통해 데이터를 읽어오는 앱을 위한 정책의 경우 아래와 같이 수정한다.
  1. 일단 앱을 실행시켜 AVC denial 로그를 확인한다.


~$ adb shell su -c dmesg | grep denied
<38>[  322.415652]  [6:    logd.auditd: 2406] [c6] type=1400 audit(1491383781.160:3): avc: denied { read write } for pid=4529 comm="Thread-158" name="spidev1.0" dev="tmpfs" ino=7687 scontext=u:r:untrusted_app:s0 tcontext=u:object_r:device:s0 tclass=chr_file permissive=1
<38>[  322.438108]  [6:    logd.auditd: 2406] [c6] type=1400 audit(1491383781.160:4): avc: denied { open } for pid=4529 comm="Thread-158" path="/dev/spidev1.0" dev="tmpfs" ino=7687 scontext=u:r:untrusted_app:s0 tcontext=u:object_r:device:s0 tclass=chr_file permissive=1
<38>[  322.460911]  [6:    logd.auditd: 2406] [c6] type=1400 audit(1491383781.160:5): avc: denied { ioctl } for pid=4529 comm="Thread-158" path="/dev/spidev1.0" dev="tmpfs" ino=7687 scontext=u:r:untrusted_app:s0 tcontext=u:object_r:device:s0 tclass=chr_file permissive=1
로그를 보면 Thread-158 에서 /dev/spidev1.0 장치에 read, write, open, ioctl을 수행하다 실패했다.  아래 정보를 확인하고 정책소스를 수정시 참고한다.
source context: untrusted_app  (프로세스 레이블)
target context: device                 (타겟 오브젝트 레이블)
target class: chr_file        (오브젝트 클래스)


2. file_contex에 spidev레이블을 myspi_dev로 설정한다.
/dev/spidev1.0             u:object_r:myspi_device:s0
  • external/sepolicy/domain.te를 보면 device:chr_file을 막았으므로, device말고 새로운 레이블이 필요하다.
    everallow { domain -unconfineddomain -ueventd -recovery } device:chr_file { open read write };


3.  아래 경로에 타겟보드의  myspi_device를 위한 정책소스를 추가한다.
device/vendor//board/sepolicy/myspidevice.te
type myspi_device, dev_type;

allow untrusted_app myspi_device:chr_file rw_file_perms;
  • external/sepolicy/global_macros 에서 rw_file_perms에  read/write/ioctl 이 포함되도록 정의 되어 있다.
    define(`r_file_perms', `{ getattr open read ioctl lock }')
    define(`w_file_perms', `{ open append write }')
    define(`rx_file_perms', `{ r_file_perms x_file_perms }')

4.myspidevice.te가 빌드시 포함되도록 device/vendor/board/BoardConfig.mk를 수정한다.
BOARD_SEPOLICY_UNION +=
myspidevice.te


5. adb shell su -c dmesg | grep denied  명령으로 정책이 잘 적용되었는 지 확인한다. 잘 적용이 되었다면 아무 메시지가 나오지 않는다.