android Honeycomb부터 USB Mass Storage 방식에서 MTP(PTP)로 PC와 연결 방식이 바뀌었습니다.
android는 Froyo에서는 External Storage를 지원 하였습니다.
Nexus One의 경우 t-flash slot이 존재 합니다.
따라서 system partition은 /system와 /data /cache로 이루어져 있고 /mnt/sdcard란 폴더에 external storage를 mount하는 방식이 였습니다.
그래서 아래와 같이 sdcard를 android에서 umount후 PC로 mount하는 방식이였습니다.
Gingerbread(Nexus S)부터는 external storage를 지원하지 않고 iPhone 처럼 내부 nand에 system와 user data를 하나의 nand에 partition을 나누는 방식으로 바뀌었습니다.
/data partition이 고정 크기이고 작기 때문에 여러 문제점이 발생합니다.
/data를 크게 주면 한정된 nand에서 user data 영역이 줄어들기 때문에 제조사에서는 무조건 /data를 크게 잡지 못합니다.
Nexus One과 Motoroi의 경우 /data가 200Mbyte도 안되기 때문에 기본 설치된 app을 포함하면 사용자가 설치할 수 있는 공간의 더 작아 집니다.
그래서 app을 설치하고 /sdcard로 옮기기가 Gingerbread부터 지원하지만 보안 문제와 app 전체를 /sdcard로 설치하는 것이 아니라 일부 데이터만 /sdcard로 옮기기 때문에 이 역시 해결책이 아니였습니다.
그래서 Honeycomb부터 /sdcard를 /data 영역의 한 폴더로 지정하고 /data와 /sdcard를 통합하였습니다.
그런데 이렇게 하니 다른 문제가 발생합니다.
android는 linux 시스템이기 때문에 /data partition이 ext4란 linux에서 지원하는 file system을 사용합니다.
Window에서 지원하지 않는 file system이기 때문에 Window 사용자들은 볼 수가 없습니다.
그래서 MTP(PTP)를 통해 서로 다른 file system을 사용가능하도록 하것 입니다.
간단하게 설명 드리면 ftp나 samba를 이용하면 Window에서 linux의 file을 볼 수 있는 것과 같이 서로 다른 file system을 emulate하는 것이 MTP(PTP)입니다.
Apple은 iTune를 통해 위에 설명한 것과 같이 동작합니다.
여기서 android가 iPhone의 방식을 쫓아 간다고 볼 수 있겠죠.
Apple에서는 iTune를 통해 file sync를 하는지 알 수 있습니다.
그런데 MTP는 Microsoft에서 PTP를 이용하여 Window Media에서 사용하기 위해 만들 protocol입니다. 그래서 Ubuntu와 Mac에서 사용하기 위해서는 설정을 해줘아 합니다.
http://www.omgubuntu.co.uk/2011/12/how-to-connect-your-android-ice-cream-sandwich-phone-to-ubuntu-for-file-access/
위에 링크에 Ubuntu에서 MTP를 사용하는 방법이 설명되어 있습니다.
하지만 mtpfs에 버그가 있어서 저의 경우에도 두대의 Ubuntu(11.04와 10.04LTS)에서 완벽하게 동작하지 않습니다.
https://bugs.launchpad.net/ubuntu/+source/mtpfs/+bug/573524
그런데 PTP로 연결하지 문제가 없이 잘 됩니다.
Google에 Window Media를 계속 빌려 쓸지 iTune와 같이 sync Manager 프로그램을 만들지 궁금해집니다.
2012년 2월 5일 일요일
2012년 1월 16일 월요일
linux cp2104 driver
CP2104 USB to Serial를 사용하는데 ubuntu에서 minicom이 안되는 문제가 있다.
찾아 보니 CP210x driver에 baudrate 초기화 버그가 있는 듯...
http://www.spinics.net/lists/linux-usb/msg56969.html
그래서 driver patch를 적용하여 보겠습니다.
자신이 사용하는 kernel 버전을 확인한다.
커널 버전 확인
$uname -a
Linux codewalker-desktop 2.6.32-38-generic #83-Ubuntu SMP Wed Jan 4 11:12:07 UTC 2012 x86_64 GNU/Linux
synaptic에서 desktop kernel source를 받는다.
linux-source, linux-source-2.6.32
아래 path로 소스 파일이 받아 진다.
/usr/src/linux-source-2.6.32.tar.bz2
/usr/src/linux-source-2.6.32/drivers/usb/serial/cp210x.c 수정한다.
$sudo make -j10
kernel 빌드 시 에러가 발생 아래와 같이 수정.
http://thangamaniarun.wordpress.com/2010/07/08/how-to-quickly-build-custom-kernel-on-ubuntu-10-04/
cp210x.ko module 만들기
$sudo make modules
$sudo make modules_install
[/lib/modules]$ ls -l
합계 20
drwxr-xr-x 4 root root 4096 2010-04-29 21:45 2.6.32-21-generic
drwxr-xr-x 5 root root 4096 2011-12-16 18:47 2.6.32-36-generic
drwxr-xr-x 5 root root 4096 2012-01-17 16:24 2.6.32-37-generic
drwxr-xr-x 5 root root 4096 2012-01-24 17:09 2.6.32-38-generic
drwxr-xr-x 3 root root 4096 2012-01-25 17:54 2.6.32.52+drm33.21
kernel 소스 Makefile에 EXTRAVERSION이 실제 설치된 kernel과 틀리다.
그래서 수동으로 cp210x.ko를 2.6.32-38-generic 폴더 밑에 파일로 바꿔주면 된다.
EXTRAVERSION이 다르지만 insmod나 hot-plugin시 문제 없이 module이 올라 간다.
혹시나 드라이버에 문제가 생기면 동일한 linux-image-generic를 synaptic에서 재설치해 주면 해결된다.
module의 EXTRAVERSION을 확인하기 위해서는 modinfo를 이용하면 된다.
alias: usb:v0FCFp1004d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0FCFp1003d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0BEDp1101d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0BEDp1100d*dc*dsc*dp*ic*isc*ip*
alias: usb:v08FDp000Ad*dc*dsc*dp*ic*isc*ip*
alias: usb:v08E6p5501d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0745p1000d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0489pE000d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0471p066Ad*dc*dsc*dp*ic*isc*ip*
alias: usb:v045Bp0053d*dc*dsc*dp*ic*isc*ip*
depends: usbserial
vermagic: 2.6.32.52+drm33.21 SMP mod_unload modversions
parm: debug:Enable verbose debugging messages (bool)
[/lib/modules/2.6.32-38-generic/kernel/drivers/usb/serial]$
찾아 보니 CP210x driver에 baudrate 초기화 버그가 있는 듯...
http://www.spinics.net/lists/linux-usb/msg56969.html
그래서 driver patch를 적용하여 보겠습니다.
자신이 사용하는 kernel 버전을 확인한다.
커널 버전 확인
$uname -a
Linux codewalker-desktop 2.6.32-38-generic #83-Ubuntu SMP Wed Jan 4 11:12:07 UTC 2012 x86_64 GNU/Linux
linux-source, linux-source-2.6.32
아래 path로 소스 파일이 받아 진다.
/usr/src/linux-source-2.6.32.tar.bz2
/usr/src/linux-source-2.6.32/drivers/usb/serial/cp210x.c 수정한다.
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 3835106..dcba930 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -201,6 +201,8 @@ static struct usb_serial_driver cp210x_device = { #define CP210X_EMBED_EVENTS 0x15 #define CP210X_GET_EVENTSTATE 0x16 #define CP210X_SET_CHARS 0x19 +#define CP210X_GET_BAUDRATE 0x1d +#define CP210X_SET_BAUDRATE 0x1e /* CP210X_IFC_ENABLE */ #define UART_ENABLE 0x0001 @@ -459,16 +461,12 @@ static void cp210x_get_termios_port(struct usb_serial_port *port, unsigned int *cflagp, unsigned int *baudp) { unsigned int cflag, modem_ctl[4]; - unsigned int baud; + u32 baud; unsigned int bits; dbg("%s - port %d", __func__, port->number); - cp210x_get_config(port, CP210X_GET_BAUDDIV, &baud, 2); - /* Convert to baudrate */ - if (baud) - baud = cp210x_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud); - + cp210x_get_config(port, CP210X_GET_BAUDRATE, &baud, sizeof(baud)); dbg("%s - baud rate = %d", __func__, baud); *baudp = baud; @@ -580,7 +578,8 @@ static void cp210x_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios) { unsigned int cflag, old_cflag; - unsigned int baud = 0, bits; + u32 baud; + unsigned int bits; unsigned int modem_ctl[4]; dbg("%s - port %d", __func__, port->number); @@ -595,8 +594,8 @@ static void cp210x_set_termios(struct tty_struct *tty, /* If the baud rate is to be updated*/ if (baud != tty_termios_baud_rate(old_termios) && baud != 0) { dbg("%s - Setting baud rate to %d baud", __func__, baud); - if (cp210x_set_config_single(port, CP210X_SET_BAUDDIV, - ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) { + if (cp210x_set_config(port, CP210X_SET_BAUDRATE, + &baud, sizeof(baud))) { dbg("Baud rate requested not supported by device"); baud = tty_termios_baud_rate(old_termios); } --
$sudo make menuconfig$sudo make -j10
kernel 빌드 시 에러가 발생 아래와 같이 수정.
ERROR-2
LD [M] ubuntu/omnibook/omnibook.o
ld: /ubuntu/omnibook/sections.lds: No such file: No such file or directory
make[2]: *** [ubuntu/omnibook/omnibook.o] Error 1
make[1]: *** [ubuntu/omnibook] Error 2
make: *** [ubuntu] Error 2
SOLUTION-2
$ sudo vi /usr/src/linux/ubuntu/omnibook/Makefile
160: #EXTRA_LDFLAGS += $(src)/sections.lds
161: EXTRA_LDFLAGS += $(PWD)/ubuntu/omnibook/sections.lds
http://thangamaniarun.wordpress.com/2010/07/08/how-to-quickly-build-custom-kernel-on-ubuntu-10-04/
cp210x.ko module 만들기
$sudo make modules
$sudo make modules_install
[/lib/modules]$ ls -l
합계 20
drwxr-xr-x 4 root root 4096 2010-04-29 21:45 2.6.32-21-generic
drwxr-xr-x 5 root root 4096 2011-12-16 18:47 2.6.32-36-generic
drwxr-xr-x 5 root root 4096 2012-01-17 16:24 2.6.32-37-generic
drwxr-xr-x 5 root root 4096 2012-01-24 17:09 2.6.32-38-generic
drwxr-xr-x 3 root root 4096 2012-01-25 17:54 2.6.32.52+drm33.21
kernel 소스 Makefile에 EXTRAVERSION이 실제 설치된 kernel과 틀리다.
그래서 수동으로 cp210x.ko를 2.6.32-38-generic 폴더 밑에 파일로 바꿔주면 된다.
EXTRAVERSION이 다르지만 insmod나 hot-plugin시 문제 없이 module이 올라 간다.
혹시나 드라이버에 문제가 생기면 동일한 linux-image-generic를 synaptic에서 재설치해 주면 해결된다.
module의 EXTRAVERSION을 확인하기 위해서는 modinfo를 이용하면 된다.
alias: usb:v0FCFp1004d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0FCFp1003d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0BEDp1101d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0BEDp1100d*dc*dsc*dp*ic*isc*ip*
alias: usb:v08FDp000Ad*dc*dsc*dp*ic*isc*ip*
alias: usb:v08E6p5501d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0745p1000d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0489pE000d*dc*dsc*dp*ic*isc*ip*
alias: usb:v0471p066Ad*dc*dsc*dp*ic*isc*ip*
alias: usb:v045Bp0053d*dc*dsc*dp*ic*isc*ip*
depends: usbserial
vermagic: 2.6.32.52+drm33.21 SMP mod_unload modversions
parm: debug:Enable verbose debugging messages (bool)
[/lib/modules/2.6.32-38-generic/kernel/drivers/usb/serial]$
2011년 12월 27일 화요일
android ICS 해상도, density에 따른 UI 변화
해상도 중 짧은 쪽이 600pixel 이상 일때 emulator의 화면입니다.
그리고 600pixel 미만일 때 emulator의 화면입니다.
동일한 AVD에서 해상도만 1024 x 600에서 800 x 480으로 변경한 것입니다.
해상도의 짧은 쪽이 600이상 일 때는 tablet의 UI를 보여 주고 600 미만 일 때는 phone의 UI를 보여 줍니다.
그리고 짧은 쪽이 600이상이 되면 자동으로 status bar가 하단에 위치 하고 screen buttons(Navigation Bar로 내부적으로 표현함)이 포함됩니다.
phone의 UI는 기본이 portrait이고 tablet의 UI는 landscape입니다.
600미만인 android에 landscape를 default로 주고 Screen Buttons(Navigation Bar)를 주면 제대로 그려지지 않습니다.
PhoneWindowManager.java를 보면 resolution, dpi를 가지고 판단하는 코드가 있습니다.
870 // Determine whether the status bar can hide based on the size
871 // of the screen. We assume sizes > 600dp are tablets where we
872 // will use the system bar.
873 int shortSizeDp = shortSize
874 * DisplayMetrics.DENSITY_DEFAULT
875 / DisplayMetrics.DENSITY_DEVICE;
876 mStatusBarCanHide = shortSizeDp < 600;
877 mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
878 mStatusBarCanHide
879 ? com.android.internal.R.dimen.status_bar_height
880 : com.android.internal.R.dimen.system_bar_height);
881
결론은 600미만의 device를 만드실 때는 반드시 portrait 타입에 LCD를 사용하시기 바랍니다.
그리고 odroid-7으로 테스트 한 것인데 ro.sf.lcd_density=120으로 주니 tablet UI로 동작은 합니다.
그리고 600pixel 미만일 때 emulator의 화면입니다.
동일한 AVD에서 해상도만 1024 x 600에서 800 x 480으로 변경한 것입니다.
해상도의 짧은 쪽이 600이상 일 때는 tablet의 UI를 보여 주고 600 미만 일 때는 phone의 UI를 보여 줍니다.
그리고 짧은 쪽이 600이상이 되면 자동으로 status bar가 하단에 위치 하고 screen buttons(Navigation Bar로 내부적으로 표현함)이 포함됩니다.
phone의 UI는 기본이 portrait이고 tablet의 UI는 landscape입니다.
600미만인 android에 landscape를 default로 주고 Screen Buttons(Navigation Bar)를 주면 제대로 그려지지 않습니다.
PhoneWindowManager.java를 보면 resolution, dpi를 가지고 판단하는 코드가 있습니다.
870 // Determine whether the status bar can hide based on the size
871 // of the screen. We assume sizes > 600dp are tablets where we
872 // will use the system bar.
873 int shortSizeDp = shortSize
874 * DisplayMetrics.DENSITY_DEFAULT
875 / DisplayMetrics.DENSITY_DEVICE;
876 mStatusBarCanHide = shortSizeDp < 600;
877 mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
878 mStatusBarCanHide
879 ? com.android.internal.R.dimen.status_bar_height
880 : com.android.internal.R.dimen.system_bar_height);
881
결론은 600미만의 device를 만드실 때는 반드시 portrait 타입에 LCD를 사용하시기 바랍니다.
그리고 odroid-7으로 테스트 한 것인데 ro.sf.lcd_density=120으로 주니 tablet UI로 동작은 합니다.
2011년 12월 24일 토요일
ODROID-7 ICS 복구 이미지
ODROID-7 ICS 복구 이미지 배포합니다.
기존 버전에는 kernel framebuffer가 landscape로 되어 있고 android를 270도 회전하여 화면 회전시 또는 멀티태스크 화면에 thumbnail 이미지 회전과 찌부러진 이미지 문제를 해결하였습니다.
터치 및 센서들도 Landscape mode로 수정하였습니다
http://dl.dropbox.com/u/4485660/odroid7_ics.zip
기존 버전에는 kernel framebuffer가 landscape로 되어 있고 android를 270도 회전하여 화면 회전시 또는 멀티태스크 화면에 thumbnail 이미지 회전과 찌부러진 이미지 문제를 해결하였습니다.
터치 및 센서들도 Landscape mode로 수정하였습니다
http://dl.dropbox.com/u/4485660/odroid7_ics.zip
2011년 12월 23일 금요일
android screen button 사용하기
ICS에 Screen button이 가능하도록 수정해 보겠습니다.
frameworks/base/core/res/res/values/config.xml 에 보면
config_showNavigationBar을 true가 되면 아래 보시는 것 처럼 screen button이 나옵니다.
보통 저 파일은 device 밑에 overlay폴더로 관리합니다.
device/hardkernel/odroid7/overlay/frameworks/base/core/res/res/values/config.xml
이 파일을 수정하시면 됩니다.
xda 사이트 참고하였습니다.
http://forum.xda-developers.com/showthread.php?t=1364757
2011년 12월 22일 목요일
android Airplane mode uncheck 안되는 문제...
modem이 없는 android 시스템에서 airplane 모드를 체크하면 다시 uncheck되지 않는 문제가 있습니다.
airplane의 설정이 ril-daemon과 상호 작용하여야 되는지 ril-daemon이 없거나 modem이 없는데 ril-daemon만 동작하면 이런 현상이 있습니다.
그래서 android/package/app/settings/src/com/android/settings/AirplaneModeEnabler.java를 아래와 같이 수정 합니다.
85 private void setAirplaneModeOn(boolean enabling) {
86 //codewalker
87 if (SystemProperties.get("init.svc.ril-daemon").equals("running")) {
88 mCheckBoxPref.setEnabled(false);
89 mCheckBoxPref.setSummary(enabling ? R.string.airplane_mode_turning_on
90 : R.string.airplane_mode_turning_off);
91 } else {
92 mCheckBoxPref.setChecked(true);
93 mCheckBoxPref.setSummary(null);
94 }
init.svc.ril-daemon property로 ril-daemon 동작 여부를 확인 할 수 있습니다.
airplane의 설정이 ril-daemon과 상호 작용하여야 되는지 ril-daemon이 없거나 modem이 없는데 ril-daemon만 동작하면 이런 현상이 있습니다.
그래서 android/package/app/settings/src/com/android/settings/AirplaneModeEnabler.java를 아래와 같이 수정 합니다.
85 private void setAirplaneModeOn(boolean enabling) {
86 //codewalker
87 if (SystemProperties.get("init.svc.ril-daemon").equals("running")) {
88 mCheckBoxPref.setEnabled(false);
89 mCheckBoxPref.setSummary(enabling ? R.string.airplane_mode_turning_on
90 : R.string.airplane_mode_turning_off);
91 } else {
92 mCheckBoxPref.setChecked(true);
93 mCheckBoxPref.setSummary(null);
94 }
init.svc.ril-daemon property로 ril-daemon 동작 여부를 확인 할 수 있습니다.
그리고 init.rc에 ril-daemon을 제거 합니다.
#service ril-daemon /system/bin/rild -l /system/lib/libreference-ril.so
# socket rild stream 660 root radio
# socket rild-debug stream 660 radio system
# user root
# group radio cache inet misc audio sdcard_rw
android screen timeout 무한대로 설정하기
아래 링크를 보면 screen timeout를 무한대로 만드는 방법이 있습니다.
http://www.aesop.or.kr/34931
sqlite3 /data/data/com.android.providers.settings/databases/settings.db "INSERT INTO system (name, value) VALUES ('screen_off_timeout', -1);"
settings app를 수정하여 무한대로 설정 할 수 있도록 수정 해 보겠습니다.
android/pacakge/app/Settings/res/values/arrays.xml을 -1 item을 추가 합니다.
74
75
76
77- 15 seconds
78- 30 seconds
79- 1 minute
80- 2 minutes
81- 10 minutes
82- 30 minutes
83- off
84
85
86
87
88
89- 15000
90
91- 30000
92
93- 60000
94
95- 120000
96
97- 600000
98
99- 1800000
100
101- -1
102
그럼 아래와 같이 UI 화면이 구성이 되고 off를 선택 하시면 -1 값이 db에 입력 되어 screen timeout이 안 걸립니다.
http://www.aesop.or.kr/34931
sqlite3 /data/data/com.android.providers.settings/databases/settings.db "INSERT INTO system (name, value) VALUES ('screen_off_timeout', -1);"
settings app를 수정하여 무한대로 설정 할 수 있도록 수정 해 보겠습니다.
android/pacakge/app/Settings/res/values/arrays.xml을 -1 item을 추가 합니다.
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
그럼 아래와 같이 UI 화면이 구성이 되고 off를 선택 하시면 -1 값이 db에 입력 되어 screen timeout이 안 걸립니다.
피드 구독하기:
글 (Atom)