ANDROID 포팅 Copyright (C) 2009 sevencore Released under the creative commons license: (CC-BY-SA-NC)
본문서는의 SC-PXA270 보드에서동작하는 ANDROID 개발환경및소프트웨어구 성을기술한다. 1. 개발환경설정및소스코드다운로드 안드로이드플랫폼은리눅스와 MacOS를기본개발운영체제로사용한다. 본문서에서는 Ubuntu Linux를사용하여기본개발환경을구축하고안드로이드소스코드를다운받는방법을설명한다. 다른 Linux를사용하거나 MacOS를사용하는경우공식안드로이드오픈소스프로젝트사이트 (http://source.android.com/) 를통해개발환경설정방밥과소스코드다운로드받는방법을확인할수있다. 안드로이드응용프로그램은에뮬레이터를통해서도개발할수있다. 안드로이드응용프로그램공식개발사이트 (http://code.google.com/intl/ko/android/intro/index.html) 를통해서개발환경을설정하고기본적인개발과정및방법들을배울수있다. 1.1. 안드로이드플랫폼개발환경설정 1.1.1. Ubuntu Linux:i386 i386 계열의 CPU를사용하고 Ubuntu를동작시키는호스트에서개발하는경우안드로이드개발을위해서다음개발툴들을설치하거나설치여부를확인한다. - Git ( 버전 1.5.4 이상 ) 와 GNU Privacy Guard $ sudo apt-get install git-core gnupg - JDK 5.0, update 12 또는그이상 $ sudo apt-get install sun-java6-j아 - Flex, bison, gperf, libs이-dev, libesd0-dev, libwxgtk2.6-dev(optional), build-essential, zip,curl $ sudo apt-get install flex bison gperf libs이-dev libesd0-dev libwxgtk2.6-dev build-essential zip curl libncurses5-dev zlib1g-dev - Valgrind, memory leaks, stack corruption, array bounds overflows 등을찾는데사용한다. $ sudo apt-get install valgrind - Intrepid(8.10) 사용자는새로운버전의 libreadline이필요할수도있다. $ sudo apt-get install lib32readline5-dev VMware 같은 virtual machne에서리눅스를사용하는경우안드로이드소스를빌드하기위해서는최소한 10GB 이상의공간을할당해야한다. 개발툴들의공식웹사이트는다음과같다. Python 2.4 : http://www.python.org/download/ JDK 5.0, update 12 : http://java.sun.com/javase/downloads/index.jsp Git 1.5.4 : http://git-scm.com/
1.1.2. Repo 설치안드로이드소스는 Git 사용하여관리되는데 repo는안드로이드소스접근을보다쉽게만들어주는툴이다. 다음과같이호스트컴퓨터에 repo를설치한다. - Repo를설치할 ~/bin 디렉토리를생성하고실행경로환경변수에추가한다. $ cd ~ $ mkdir bin $ export PATH=~/bin/:$PATH ( 리눅스쉘종류에따라 export 대신 set이사용될수있다.) $ echo $PATH - Repo 스크립트를다운로드하고실행파일로속성을변경한다. $ curl http://android.git.kernel.org/repo > ~/bin/repo $ chmod ax ~/bin/repo Curl 명령을실행할때실행권한문제가발생하는경우 root 계정으로변경한후 repo를설치한다. 1.1.3. Repo 클라이언트초기화 - 안드로이드소스를다운받을작업디렉토리를생성한다. $ make ~/ANDROID_SOURCE $ cd ~/ANDROID_SOURCE - 최신버전의 repo를다운받기위해 repo init을실행한다. $ repo init u git://android.git.kernel.org/platform/manifest.git - repo init을실행할때이름과이메일주소를물어보는데자신이수정한안드로이드소스를배포할계획이없다면적당히입력해도상관없다. 1.1.4. 파일다운로드및빌드안드로이드소스를다운로드할디렉토리로이동하여다음명령을실행한다. $ repo sync 안드로이드소스트리의최상위디렉토리에서 make를실행하므로소스코드전체 ( 커널제외 ) 를빌드할수있다. 커널을포팅할보드에맞춰서설정및수정한수따로빌드한다. $ cd ~/ANDROID_SOURCE $ make run-java-tool과관련하여에러가발생해소스코드빌드에실패한경우다음과같이환경변수를설정해준다. $ export ANDROID_JAVA_HOME = $JAVA_HOME 안드로이드플랫폼소스전체를빌드하려면 7GB 정도의공간이필요하고호스트컴퓨터의성능에따라다르겠지만많은시간이필요할것이다 1.2. 안드로이드응용프로그램개발환경설정
안드로이드는현재 ARM 계열의시스템에서동작하도록되어있지만에뮬레이터를사용하여일반윈도우환경에서도안드로이드응용프로그램을개발할수있다. 1.3. 안드로이드 SDK 설치 1.3.1. 개발툴준비안드로이드 SDK를사용해응용프로그램을개발하기위해서는다음과같은개발환경이필요하다. - 운영체제 n WindowXP 또는 Vista n Mac OS X 10.4.8 또는그이상의버전 (x86 only) n Linux (Ubuntu Dapper Drake) - 개발툴 n Eclipse 3.3(Europa), 3.4(Ganymede) n JDK 5 또는 JDK 6 n Android Development Tools plugin 1.3.2. 안드로이드 SDK 다운로드및설치 안드로이드응용프로그램개발을위한 SDK는공식사이트를통해서다운로드받을수있다. (http://code.google.com/intl/ko/android/download.html) 안드로이드 SDK를다운로드받은후적절한위치에압축을푼다. 기본적으로안드로이드 SDK 는 android_sdk_<platform>_<release>_<build> 형태의 이름을 갖고 디렉토리에 tools/ 와 samples/ 라는서브디렉토리가생성된다. Tools 디렉토리를실행경로에추가한다. - 윈도우환경 n 내컴퓨터에서오른쪽마우스클릭 n 속성선택 n 고급탭아래에환경변수버튼클릭 n 다이얼로그화면이나타나면시스템변수의 Path 값을 tools/ 디렉토리가있는경로를 추가하여수정한다. - 리눅스환경 n Export PATH=${PATH:<your_sdk_dir>/tools - Mac OS n.bash_profile 수정 1.3.3. Eclipse 플러그인 (ADT) 설치 Android Development Tools(ADT) 는안드로이드응용프로그램을빠르고쉽게생성, 실행, 디버깅할수있도록하는이클립스용플러그인이다. 본문서에서는 Eclipse 3.4(Ganymede) 를사용한다고가정한다. Eclipse 3.3(Europa) 를사용하는경우는공식사이트를통해설치방법을참고하길바란다. (http://code.google.com/intl/ko/android/intro/installing.html)
Eclipse 3.4 (Ganymede) I) 이클립스실행 Help -> Software Updates II) 다이얼로그가나타나면 Available Software 탭클릭 III) Add site 클릭 IV) https://dl-ssl.google.com/android/eclipse/ OK 클릭 V) 다시 Available Software view로돌아갔을때플러그인이보이지않으면위의주소가잘못된경우이므로 IV) 에서 http://dl-ssl.google.com/android/eclipse/ 으로다시입력한다. 체크박스를선택하고 install을클릭한다. VI) 이어서나타나는윈도우에 Android Developer Tools와 Android Editors가체크되어있는지확인한다. VII) 라이선스에동의하고 Finish를클릭한다. VIII) 이클립스를다시시작한다. IX) Window -> Preferences 실행 X) 왼쪽패널에서안드로이드를선택하고 SDK의위치를지정한후 Apply와 OK를순서대로클릭한다. 1.3.4. HelloWorld 실행 - 프로젝트생성 (File -> New -> Project)
- 프로젝트의세부항목을채운다. - 프로젝트의 HelloAndroid>src>com>android>hello 아래의 HelloAndroid.java 의내용을확인 한다. - HelloAndroid.java 를다음과같이수정한다. package com.android.hello; import android.app.activity; import android.os.bundle;
import android.widget.textview; public class HelloAndroid extends Activity { /** Called when the activity is first created. */ @Override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); TextView tv = new TextView(this); tv.settext("hello, Android"); setcontentview(tv); - Run(Ctrl F11) 안드로이드실행 - 안드로이드에뮬레이터실행화면
2. 안드로이드리눅스커널 안드로이드리눅스커널은소스코드패키지중에서 kernel 디렉토리에있다. Makefile을통해서커널버전을확인할수있다. SC-PXA270 보드에는안드로이드소스코드프로젝트공식사이트에서배포한 2.6.27 안드로이드리눅스커널을디바이스드라이버와함께포팅하였다. 특별히안드로이드를포팅을위해일반리눅스디바이스드라이버와다른부분은프레임버퍼와입력장치, 커널설정이있다. 2.1. 커널설정 안드로이드를위해서반드시필요한커널설정은다음과같다. CONFIG_AEABI=y CONFIG_OABI_COMPAT=y CONFIG_ANDROID_POWER=y CONFIG_ANDROID_PMEM=y CONFIG_BINDER_IPC=y CONFIG_LOW_MEMORY_KILLER=y 2.2. 커널컴파일 make 또는 make zimage 수행 2.3. 프레임버퍼 안드로이드는더블버퍼링부분과프레임버퍼 ioctl 함수인 file operation인.fb_pan_display 코드를작성해야한다. 다음과같이 pxafb.c 파일수정 --- pxafb_old.c 2009-01-28 10:46:00.000000000 0900 pxafb_new.c 2009-02-24 15:25:10.000000000 0900 @@ -50,7 50,7 @@ #include <asm/irq.h> #include <asm/div64.h> #include <mach/pxa-regs.h> -#include <mach/pxa2xx-gpio.h> #include <mach/mfp-pxa27x.h> #include <mach/bitfield.h> #include <mach/pxafb.h> @@ -69,6 69,8 @@ #define LCCR3_INVALID_CONFIG_MASK (LCCR3_HSP LCCR3_VSP \
LCCR3_PCD LCCR3_BPP) #define C_CHANGE_DMA_BASE (10) static void (*pxafb_backlight_power)(int); static void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *); @@ -309,7 311,7 @@ var->sync var->grayscale var->xres_virtual = mode->sync; = var->xres; = mode->cmap_greyscale; - var->yres_virtual = var->yres; var->yres_virtual = var->yres * 2; /* @@ -350,7 352,7 @@ var->xres_virtual = max(var->xres_virtual, var->xres); var->yres_virtual = - max(var->yres_virtual, var->yres); max(var->yres_virtual, var->yres * 2); /* * Setup the RGB parameters for this display. @@ -516,6 518,34 @@ return -EINVAL; #ifdef CONFIG_ANDROID_POWER static void pxafb_early_suspend(android_early_suspend_t *h) { #if 0 struct pxafb_info *fb = container_of(h, struct pxafb_info, early_suspend); #endif
static void pxafb_late_resume(android_early_suspend_t *h) { #if 0 struct pxafb_info *fb = container_of(h, struct pxafb_info, early_suspend); #endif #endif static int pxafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { struct pxafb_info *fbi = (struct pxafb_info *)info; fbi->fb.var.yoffset = var->yoffset; pxafb_schedule_work(fbi, C_CHANGE_DMA_BASE); return 0; static struct fb_ops pxafb_ops = {.owner.fb_check_var = THIS_MODULE, = pxafb_check_var, @@ -526,6 556,7 @@.fb_imageblit = cfb_imageblit,.fb_blank.fb_mmap = pxafb_blank, = pxafb_mmap,.fb_pan_display = pxafb_pan_display, ; /* @@ -814,17 845,6 @@ return 0; -#elif CONFIG_FB_NX1009 -
-int pxafb_smart_queue(struct fb_info *info, uint16_t *cmds, int n_cmds) -{ - return 0; - - -int pxafb_smart_flush(struct fb_info *info) -{ - return 0; - #else @@ -1221,6 1241,8 @@ pxafb_backlight_power(fbi, 1); break; case C_CHANGE_DMA_BASE: fbi->fb.fix.smem_start = fbi->screen_dma (fbi->fb.var.xres*fbi->fb.var.yoffset*fbi->fb.var.bits_per_pixel/8); mutex_unlock(&fbi->ctrlr_lock); @@ -1373,6 1395,7 @@ for (i = 0; i < num_modes; i) { smemlen = modes[i].xres * modes[i].yres * modes[i].bpp / 8; smemlen *= 2; if (smemlen > fbi->fb.fix.smem_len) fbi->fb.fix.smem_len = smemlen; @@ -1451,7 1474,7 @@ fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS; fbi->fb.fix.type_aux = 0; fbi->fb.fix.xpanstep = 0; - fbi->fb.fix.ypanstep = 0; fbi->fb.fix.ypanstep = 1; fbi->fb.fix.ywrapstep = 0;
fbi->fb.fix.accel = FB_ACCEL_NONE; @@ -1853,6 1876,12 @@ CPUFREQ_POLICY_NOTIFIER); #endif #ifdef CONFIG_ANDROID_POWER fbi->early_suspend.suspend = pxafb_early_suspend; // fbi->early_suspend.resume = pxafb_late_resume; android_register_early_suspend(&fbi->early_suspend); #endif /* * Ok, now enable the LCD controller */ @@ -1945,3 1974,4 @@ MODULE_DESCRIPTION("loadable framebuffer driver for PXA"); MODULE_LICENSE("GPL"); pxafb.h 파일을다음과같이수정 --- pxafb_old.h 2009-01-09 07:48:59.000000000 0900 pxafb_new.h 2009-02-24 15:26:45.000000000 0900 @@ -21,6 21,12 @@ * for more details. */ #ifdef CONFIG_ANDROID_POWER #include <linux/android_power.h> /* android_early_suspend_t */ #endif /* PXA LCD DMA descriptor */ struct pxafb_dma_descriptor { unsigned int fdadr;
@@ -124,6 130,11 @@ struct notifier_block struct notifier_block freq_transition; freq_policy; #endif #ifdef CONFIG_ANDROID_POWER android_early_suspend_t early_suspend; #endif ; #define TO_INF(ptr,member) container_of(ptr,struct pxafb_info,member) @@ -149,3 160,4 @@ #define MIN_YRES 64 #endif /* PXAFB_H */ 2.4. 입력장치 2.4.1. 싱글터치스크린안드로이드는일반리눅스의 tslib 가지원하지않는다. 그러므로터치칲에서받은데이터를디바이스드라이버에서가공해실제 LCD 해상도에해당하는값으로응용프로그램에전달한다. 다음코드는 TSC2007 터치칩과 800 x 480의해상도를가진 LCD를사용할경우이다. input device 초기화 input_dev->evbit[0] = BIT_MASK(EV_KEY) BIT_MASK(EV_ABS) BIT_MASK(EV_SYN); input_dev->keybit[bit_word(btn_touch)] = BIT_MASK(BTN_TOUCH); input_dev->absbit[0] = BIT(ABS_X) BIT(ABS_Y); input_set_abs_params(input_dev, ABS_X, 0, 800, 0, 0); input_set_abs_params(input_dev, ABS_Y, 0, 480, 0, 0); input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0, 0, 0); 터치칲에서받은좌료를 input device 에게전달함수 static void tsc2007_send_event(void *tsc)
{ struct tsc2007 *ts = tsc; u32 Rt; u16 x, y, z1, z2; u16 report_x = 0; u16 report_y = 0; static u16 prev_x = 0; static u16 prev_y = 0; x = ts->tc.x; y = ts->tc.y; z1 = ts->tc.z1; z2 = ts->tc.z2; /* range filtering */ if (x == MAX_12BIT) x = 0; if (likely(x && z1)) { /* compute touch pressure resistance using equation #1 */ Rt = z2; Rt -= z1; Rt *= x; Rt *= ts->x_plate_ohms; Rt /= z1; Rt = (Rt 2047) >> 12; else Rt = 0; if (Rt > MAX_12BIT) { dev_dbg(&ts->client->dev, "ignored pressure %d\n", Rt); complete(&ts->penirq_completion); return; if (Rt) { struct input_dev *input = ts->input;
if (!ts->pendown) { input_report_key(input, BTN_TOUCH, 1); ts->pendown = 1; report_x = x * 800 / MAX_12BIT; report_x = 800 - report_x; report_y = y * 480 / MAX_12BIT; if (report_x > 800 report_x <= 0 ) report_x = prev_x; if (report_y > 480 report_y <= 0 ) report_y = prev_y; input_report_abs(input, ABS_X, report_x); input_report_abs(input, ABS_Y, report_y); input_report_abs(input, ABS_PRESSURE, z1); input_report_key(input, BTN_TOUCH, 1); input_sync(input); prev_x = report_x; prev_y = report_y;
3. 안드로이드루트파일시스템 이번장에서는빌드된안드로이드플랫폼소스에서안드로이드루트파일시스템을구성하고실 제보드에서실행하는방법을설명한다. 3.1. 안드로이드루트파일시스템구성 위에서설명한것처럼안드로이드플랫폼소스를다운로드받고빌드를실행하면 out/ 디렉토리가새로생성되면서빌드결과물이복사된다. 안드로이드루트파일시스템은 out/target/product/generic/ 아래에생성된다. out/target/product/generic 아래의 root 디렉토리가안드로이드루트파일시스템디렉토리이다. - 안드로이드루트파일시스템디렉토리로이동 $ cd [ 안드로이드작업디렉토리 ]/out/product/generic/ $ ls root data default.prop dev init init.goldfish.rc init.rc proc sbin sys system root/ 디렉토리의대부분의디렉토리는비어있는데실제로안드로이드프로그램이들어있는 system/ 디렉토리는 root/ 디렉토리밖에따로구성되어있다. 그러므로완전한안드로이드루트파일시스템을만들기위해서는 root/system/ 아래에 system/ 디렉토리의내용이모두복사되어야한다. - System/ 디렉토리내용확인 $ ls root/system $ ls system app bin build.prop etc fonts framework lib media sounds usr xbin - System/ 디렉토리내용복사 $ cp a system/* root/system/ - 디바이스노드생성 ( 이전파일시스템에서복사하거나새로생성한다.) $ cp a [ 기존의루트파일시스템 ]/dev/* root/dev/ 또는 $ cd root/dev/ $ mknod [device node name] [c/b] [major number] [minor number] SCPXA270R5 보드에는다음과같이노드가생성되어있다. crw-r--r-- 1 root root 10, 134 Nov 22 2006 apm_bios crw------- 1 root root 14, 4 Dec 5 2007 audio crw------- 1 root root 14, 20 Dec 5 2007 audio1 crw-rw-rw- 1 root root 14, 36 Dec 5 2007 audio2 crw-rw-rw- 1 root root 14, 52 Dec 5 2007 audio3 crw------- 1 root root 14, 7 Dec 5 2007 audioctl crw--w--w- 1 root root 5, 1 Dec 5 2007 console
crw------- 1 root root 14, 3 Dec 5 2007 dsp crw------- 1 root root 14, 19 Dec 5 2007 dsp1 crw-rw-rw- 1 root root 14, 35 Dec 5 2007 dsp2 crw-rw-rw- 1 root root 14, 51 Dec 5 2007 dsp3 lrwxrwxrwx 1 root root 3 Feb 17 20:24 fb -> fb0 crw------- 1 root root 29, 0 Dec 5 2007 fb0 crw------- 1 root root 29, 1 Dec 5 2007 fb1 crw------- 1 root root 29, 2 Dec 5 2007 fb2 crw------- 1 root root 29, 3 Dec 5 2007 fb3 crw------- 1 root root 29, 4 Dec 5 2007 fb4 crw------- 1 root root 29, 5 Dec 5 2007 fb5 crw------- 1 root root 29, 6 Dec 5 2007 fb6 crw------- 1 root root 29, 7 Dec 5 2007 fb7 prw------- 1 root root 0 Dec 5 2007 initctl drwxr-xr-x 2 root root 4096 Dec 5 2007 input crw-r--r-- 1 root 1016 10, 90 Jan 7 2008 ipm crw-r--r-- 1 root 1016 233, 0 Jan 7 2008 ipmc crw-r----- 1 root root 1, 2 Dec 5 2007 kmem brw-rw---- 1 root root 7, 0 Dec 5 2007 loop0 brw-rw---- 1 root root 7, 1 Dec 5 2007 loop1 brw-rw---- 1 root root 7, 2 Dec 5 2007 loop2 crw-r----- 1 root root 1, 1 Dec 5 2007 mem crw------- 1 root root 14, 2 Dec 5 2007 midi00 crw------- 1 root root 14, 18 Dec 5 2007 midi01 crw------- 1 root root 14, 34 Dec 5 2007 midi02 crw------- 1 root root 14, 50 Dec 5 2007 midi03 crw------- 1 root root 14, 0 Dec 5 2007 mixer crw------- 1 root root 14, 16 Dec 5 2007 mixer1 crw-rw-rw- 1 root root 14, 32 Dec 5 2007 mixer2 crw-rw-rw- 1 root root 14, 48 Dec 5 2007 mixer3 brw-r--r-- 1 root root 254, 0 Nov 22 2006 mmcblk brw-r--r-- 1 root root 254, 1 Nov 22 2006 mmcblk0 lrwxrwxrwx 1 root root 5 Feb 17 20:24 mouse -> psaux crw-rw-r-- 1 root root 90, 0 Dec 5 2007 mtd0 crw-rw-r-- 1 root root 90, 2 Dec 5 2007 mtd1 crw-rw-r-- 1 root root 90, 4 Dec 5 2007 mtd2 crw-rw-r-- 1 root root 90, 6 Dec 5 2007 mtd3
crw-rw-r-- 1 root root 90, 8 Dec 5 2007 mtd4 crw-rw-r-- 1 root root 90, 10 Dec 5 2007 mtd5 brw-rw-r-- 1 root root 31, 0 Dec 5 2007 mtdblock0 brw-rw-r-- 1 root root 31, 1 Dec 5 2007 mtdblock1 brw-rw-r-- 1 root root 31, 2 Dec 5 2007 mtdblock2 brw-rw-r-- 1 root root 31, 3 Dec 5 2007 mtdblock3 brw-rw-r-- 1 root root 31, 4 Dec 5 2007 mtdblock4 brw-rw-r-- 1 root root 31, 5 Dec 5 2007 mtdblock5 crw-rw-rw- 1 root root 1, 3 Dec 5 2007 null crw------- 1 root root 108, 0 Dec 5 2007 ppp crw------- 1 root root 10, 1 Dec 5 2007 psaux crw-rw-rw- 1 root root 5, 2 Dec 5 2007 ptmx drwxr-xr-x 2 root root 4096 Dec 5 2007 pts crw-r--r-- 1 root root 254, 0 Nov 22 2006 pvrsrv brw-rw---- 1 root root 1, 0 Dec 5 2007 ram0 crw-r--r-- 1 root root 1, 8 Dec 5 2007 random brw-rw---- 1 root root 8, 0 Dec 5 2007 sda brw-rw---- 1 root root 8, 1 Dec 5 2007 sda1 crw------- 1 root root 14, 1 Dec 5 2007 sequencer drwxr-xr-x 2 root root 4096 Aug 1 2006 snd crw------- 1 root root 14, 6 Dec 5 2007 sndstat crw-r--r-- 1 root root 11, 0 Dec 5 2007 ts crw-rw-rw- 1 root root 5, 0 Dec 5 2007 tty crw--w---- 1 root root 4, 0 Dec 5 2007 tty0 crw--w---- 1 root root 4, 1 Dec 5 2007 tty1 crw------- 1 root root 4, 2 Dec 5 2007 tty2 crw------- 1 root root 4, 3 Dec 5 2007 tty3 crw------- 1 root root 4, 4 Dec 5 2007 tty4 crw------- 1 root root 4, 5 Dec 5 2007 tty5 crw------- 1 root root 4, 6 Dec 5 2007 tty6 crw--w---- 1 root root 4, 7 Dec 5 2007 tty7 crw--w---- 1 root root 4, 8 Dec 5 2007 tty8 crw--w---- 1 root root 4, 9 Dec 5 2007 tty9 crw-r--r-- 1 root root 166, 0 Dec 12 2006 ttyacm0 crw-rw---- 1 root root 4, 64 Dec 5 2007 ttys0 crw-rw---- 1 root root 4, 65 Dec 5 2007 ttys1 crw-r--r-- 1 root root 1, 9 Dec 5 2007 urandom
crw------- 1 root root 81, 0 Dec 5 2007 video0 crw------- 1 root root 81, 1 Dec 5 2007 video1 crw-rw-rw- 1 root root 1, 5 Dec 5 2007 zero - 루트파일시스템압축 $ tar cfz android_rootfs.tar.gz root/ 3.2. 안드로이드루트파일시스템사용 안드로이드루트파일시스템은 EXT3나 YAFFS2 파일시스템에서만정상적으로동작한다. 압축된안드로이드루트파일시스템은약 32MB이므로 SCPXA270R5 보드의 NAND flash memory에안드로이드루트파일시스템을복사한다. 3.2.1. 안드로이드루트파일시스템을 YAFFS2로사용 - NAND flash를 YAFFS2로마운트 $ mount t yaffs2 /dev/mtdblock4 /mnt/mtd1 - MMC 카드를이용해안드로이드루트파일시스템복사 $ mount t vfat /dev/mmcblk0 /mnt/card $ cd /mnt/mtd1 $ tar zxf /mnt/card/android_rootfs.tar.gz $ ls /mnt/mtd1 root lostfound $ mv root android 안드로이드를실행하기위해서는안드로이드루트디렉토리로루트파일시스템을변경하고 init 프로세스를실행한다. $ chroot /mnt/mtd1/android /init ANDROID_ 가콘솔창에출력되고안드로이드로봇이보인후안드로이드초기화면을볼수있다. 안드로이드가자동으로부팅되게하려면기존루트파일시스템의실행스크립트를수정해위에서설명한디바이스마운트, 안드로이드루트파일시스템변경, init 프로세스실행이자동으로실행되도록한다. 3.2.2. 안드로이드루트파일시스템을 EXT3로사용 MMC 카드를 EXT3로포맷한후 MMC 카드를사용해안드로이드를부팅할수있다. 개발환경에서루트파일시스템의변경이잦은경우 MMC 카드를이용해부팅하면루트파일시스템을보드로복사할필요가없으므로개발시간을줄일수있다. - MMC 카드를 EXT3로포맷 (MMC 카드를 usb 젠더를사용해서호스트에연결 )
# mkfs.ext3 /dev/sda - 안드로이드루트파일시스템을 MMC로복사 $ cp root/ /mnt/card/android - MMC 카드를보드에 EXT3로마운트 # mount t ext3 /dev/mmcblk0 /mnt/card - 안드로이드루트파일시스템으로루트파일시스템을변경하고 init 프로세스실행 # chroot /mnt/card/android /init