2013년 3월 25일 월요일

GMS apps install without PC for ODROID

Connect USB Keyboard.

1. Download GAPPS from Broswer









http://goo.im/gapps/


ICS

gapps-ics-20120429-signed.zip

JB

gapps-jb-20121011-signed.zip

2. Run File Explorer




3. Unzip by File Explorer app.

  






4. Run Terminal 





5. get Root

#su




6. remount /system patition to rw

#mount -o rw,remount /system


root@android:/sdcard/Download # mount                                           
rootfs / rootfs ro,relatime 0 0                                                 
tmpfs /dev tmpfs rw,nosuid,relatime,mode=755 0 0                                
devpts /dev/pts devpts rw,relatime,mode=600 0 0                                 
proc /proc proc rw,relatime 0 0                                                 
sysfs /sys sysfs rw,relatime 0 0                                                
none /acct cgroup rw,relatime,cpuacct 0 0                                       
tmpfs /mnt/asec tmpfs rw,relatime,mode=755,gid=1000 0 0                         
tmpfs /mnt/obb tmpfs rw,relatime,mode=755,gid=1000 0 0                          
none /dev/cpuctl cgroup rw,relatime,cpu 0 0                                     
/dev/block/mmcblk0p2 /system ext4 rw,relatime,barrier=1,data=ordered 0 0        
/dev/block/mmcblk0p3 /data ext4 rw,nosuid,nodev,noatime,barrier=1,nodelalloc,da0
/dev/block/mmcblk0p4 /cache ext4 rw,nosuid,nodev,noatime,barrier=1,nomblk_io_su0
none /proc/bus/usb usbfs rw,relatime,devmode=666 0 0                            
/dev/block/vold/179:1 /mnt/sdcard vfat rw,dirsync,nosuid,nodev,noexec,relatime,0
/dev/block/vold/179:1 /mnt/secure/asec vfat rw,dirsync,nosuid,nodev,noexec,rela0
tmpfs /mnt/sdcard/.android_secure tmpfs ro,relatime,size=0k,mode=000 0 0        
root@android:/sdcard/Download # 

7. cp gapps files


/system/bin/busybox cp -rv /sdcard/Download/gapp-jb-20121011-signed/system/* /system/


8. change permissions


#cd /system/app
#chmod 644 *
#sync
#reboot

9. finish











2013년 1월 28일 월요일

Makefile에서 "-=" 문제

android 4.1.1에서 busybox가 컴파일이 안된다.
문제는 -fno-strict-volatile-bitfields다.
4.2.1에서는 컴파일이 되는데 4.1.1에서는 안된다.

build/core/combo/TARGET_linux-arm.mk


120 # by turning off the builtin sin function.                          
121 ifneq ($(filter 4.6.%, $(shell $(TARGET_CC) --version)),)          
122 TARGET_GLOBAL_CFLAGS += -Wno-unused-but-set-variable -fno-builtin-sin \
123             -fno-strict-volatile-bitfields                                                          
124 endif                                                                  
125        


그래서 저 옵션만 끄면 되것 같아서 아래와 같이 해 보았다.

TARGET_GLOBAL_CFLAGS -= -fno-strict-volatile-bitfields

물론 -=가 될줄 알았는데 안된다.

그래서 할 수 없이 TARGET_GLOBAL_CFLAGS에서 -fno-strict-volatile-bitfields를 없애고 다른 변수를 선언하기로 했다.

TARGET_GLOBAL_CFLAGS2 := $(shell echo $(TARGET_GLOBAL_CFLAGS) | sed 's/-fno-strict-volatile-bitfields/ /g')

2012년 10월 18일 목요일

Navigation Bar에 volume up/down, Shutdown, Screenshot 버튼 넣어보기





Tablet UI에서 back, home. recent app 옆에  volume up/down, Shutdown, Screenshot button을 넣어보자.

먼저 frameworks/base/packages/SystemUI/res/drawable-[h,m,x]dpi/에
ic_sysbar_home.png와 동일한 크기의 
ic_sysbar_plus,png, ic_sysbar_minus.png, ic_sysbar_shutdown.png, ic_sysbar_screenshot.png 이란 이미지를 준비합니다.

frameworks/base/packages/SystemUI/res/layout/navigation_bar.xml 에 recent_apps 다음에 4개의 항목을 추가합니다.

 <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
                android:layout_width="80dp"
                android:layout_height="match_parent"
                android:src="@drawable/ic_sysbar_recent"
                android:layout_weight="0"
                systemui:glowBackground="@drawable/ic_sysbar_highlight"
                android:contentDescription="@string/accessibility_recent"
                />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/vol_plus"
                android:layout_width="80dp"
                android:layout_height="match_parent"
                android:src="@drawable/ic_sysbar_plus"
                android:layout_weight="0"
                systemui:glowBackground="@drawable/ic_sysbar_highlight"
                android:contentDescription="@string/accessibility_recent"
                />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/vol_minus"
                android:layout_width="80dp"
                android:layout_height="match_parent"
                android:src="@drawable/ic_sysbar_minus"
                android:layout_weight="0"
                systemui:glowBackground="@drawable/ic_sysbar_highlight"
                android:contentDescription="@string/accessibility_recent"
                />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/shutdown"
                android:layout_width="80dp"
                android:layout_height="match_parent"
                android:src="@drawable/ic_sysbar_shutdown"
                android:layout_weight="0"
                systemui:glowBackground="@drawable/ic_sysbar_highlight"
                android:contentDescription="@string/accessibility_recent"
                />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/screenshot"
                android:layout_width="80dp"
                android:layout_height="match_parent"
                android:src="@drawable/ic_sysbar_screenshot"
                android:layout_weight="0"
                systemui:glowBackground="@drawable/ic_sysbar_highlight"
                android:contentDescription="@string/accessibility_recent"
                />

frameworks/base/packages/SystemUI/res/layout-sw600dp/status_bar.xml도 동일하게 수정 합니다.

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java 에서 volume up/down과 shutdown을 구현합니다.


//volume control
import android.media.AudioManager;
//shutdown
import com.android.internal.app.ShutdownThread;
//screenshot
import android.content.ComponentName;
import android.content.ServiceConnection;
import android.os.Messenger;


    ImageView mBackButton;
    View mHomeButton;
    View mMenuButton;
    View mRecentButton;
//버튼 3개 추가
    View mVolPlusButton;
    View mVolMinusButton;
    View mShutdownButton;
    View mScreenshotButton;

    ViewGroup mFeedbackIconArea; // notification icons, IME icon, compat icon
    InputMethodButton mInputMethodSwitchButton;
    CompatModeButton mCompatModeButton;





    // used to notify status bar for suppressing notification LED
    private boolean mPanelSlightlyVisible;

AudioManager mAudioManager;

    public Context getContext() { return mContext; }






        mMenuButton = mNavigationArea.findViewById(R.id.menu);
        mRecentButton = mNavigationArea.findViewById(R.id.recent_apps);
        mRecentButton.setOnClickListener(mOnClickListener);
mVolPlusButton = mNavigationArea.findViewById(R.id.vol_plus);
        mVolPlusButton.setOnClickListener(mOnClickListener);
mVolMinusButton = mNavigationArea.findViewById(R.id.vol_minus);
        mVolMinusButton.setOnClickListener(mOnClickListener);
mShutdownButton = mNavigationArea.findViewById(R.id.shutdown);
        mShutdownButton.setOnClickListener(mOnClickListener);

mScreenshotButton = mNavigationArea.findViewById(R.id.screenshot);
        mScreenshotButton.setOnClickListener(mOnClickListener);

        LayoutTransition lt = new LayoutTransition();











        mHomeButton.setVisibility(disableHome ? View.INVISIBLE : View.VISIBLE);
        mRecentButton.setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
        mVolPlusButton.setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
        mVolMinusButton.setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
        mShutdownButton.setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
        mScreenshotButton.setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);

        mInputMethodSwitchButton.setScreenLocked(
                (visibility & StatusBarManager.DISABLE_SYSTEM_INFO) != 0);













    private View.OnClickListener mOnClickListener = new View.OnClickListener() {
        public void onClick(View v) {
if (mAudioManager == null)
mAudioManager = (AudioManager)getContext().getSystemService(Context.AUDIO_SERVICE);
            if (v == mRecentButton) {
                onClickRecentButton();
            } else if (v == mInputMethodSwitchButton) {
                onClickInputMethodSwitchButton();
            } else if (v == mCompatModeButton) {
                onClickCompatModeButton();
            } else if (v == mVolPlusButton) {
mAudioManager.handleKeyDown(KeyEvent.KEYCODE_VOLUME_DOWN, AudioManager.STREAM_MUSIC);
} else if (v == mVolMinusButton) {
mAudioManager.handleKeyDown(KeyEvent.KEYCODE_VOLUME_UP, AudioManager.STREAM_MUSIC);
} else if (v == mShutdownButton) {
ShutdownThread.shutdown(mContext,true);
}

} else if (v == mScreenshotButton) {
takeScreenshot(); 
}
        }
    };

final Object mScreenshotLock = new Object();
    ServiceConnection mScreenshotConnection = null;

    final Runnable mScreenshotTimeout = new Runnable() {
        @Override public void run() {
            synchronized (mScreenshotLock) {
                if (mScreenshotConnection != null) {
                    mContext.unbindService(mScreenshotConnection);
                    mScreenshotConnection = null;
                }
            }
        }
    };

    // Assume this is called from the Handler thread.
    private void takeScreenshot() {
        synchronized (mScreenshotLock) {
            if (mScreenshotConnection != null) {
                return;
            }
            ComponentName cn = new ComponentName("com.android.systemui",
                    "com.android.systemui.screenshot.TakeScreenshotService");
            Intent intent = new Intent();
            intent.setComponent(cn);
            ServiceConnection conn = new ServiceConnection() {
                @Override
                public void onServiceConnected(ComponentName name, IBinder service) {
                    synchronized (mScreenshotLock) {
                        if (mScreenshotConnection != this) {
                            return;
                        }
                        Messenger messenger = new Messenger(service);
                        Message msg = Message.obtain(null, 1);
                        final ServiceConnection myConn = this;
                        Handler h = new Handler(mHandler.getLooper()) {
                            @Override
                            public void handleMessage(Message msg) {
                                synchronized (mScreenshotLock) {
                                    if (mScreenshotConnection == myConn) {
                                        mContext.unbindService(mScreenshotConnection);
                                        mScreenshotConnection = null;
                                        mHandler.removeCallbacks(mScreenshotTimeout);
                                    }
                                }
                            }
                        };
                        msg.replyTo = new Messenger(h);
                        msg.arg1 = msg.arg2 = 0;
                        //if (mStatusBar != null && mStatusBar.isVisibleLw())
                            msg.arg1 = 1;
                        //if (mNavigationBar != null && mNavigationBar.isVisibleLw())
                            msg.arg2 = 1;
                        try {
                            messenger.send(msg);
                        } catch (RemoteException e) {
                        }
                    }
                }
                @Override
                public void onServiceDisconnected(ComponentName name) {}
            };
            if (mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE)) {
                mScreenshotConnection = conn;
                mHandler.postDelayed(mScreenshotTimeout, 10000);
            }
        }

    }

2012년 10월 17일 수요일

자동으로 Wi-Fi on/off하기

무제한 요금제를 사용하지만 Wi-Fi의 환경이 더 빠르기 때문에 사무실이나 집에서 전원을 연결하고 Wi-Fi를 사용합니다.
그리고 이동 중에는 Wi-Fi를 off합니다.
그래서 자동으로 충전 중이면 Wi-Fi를 켜주고 충전이 아니면 Wi-Fi를 끄는 app을 만들어 봤습니다.

추가적으로 빈 Activity에 사용여부 확인 가능한 checkbox를 추가하였습니다.


http://dl.dropbox.com/u/4485660/WiFiAuto.apk

아주 간단한 프로그램인데 BroadcastReceiver 상속받은 class만으로 app을 만들어 보니 ACTION_POWER_CONNECT intent를 못 받아서 삽질 좀 했네요.
그래서 아무 동작하지 않는 Activity를 추가 하였습니다.


--- ACConnectReceiver.java ---


package com.hardkernel.odroid.wifiauto;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiManager;

public class ACConnectReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String action = intent.getAction();
WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
if (action.equals(Intent.ACTION_POWER_CONNECTED)) {
manager.setWifiEnabled(true);
} else if (action.equals(Intent.ACTION_POWER_DISCONNECTED)) {
manager.setWifiEnabled(false);
}
}

}


--- MainActivity.java ---



package com.hardkernel.odroid.wifiauto;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);

setContentView(R.layout.main_layout);

CheckBox cbUse = (CheckBox)findViewById(R.id.cb_use);
cbUse.setOnCheckedChangeListener(new OnCheckedChangeListener () {

@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
// TODO Auto-generated method stub
SharedPreferences prefs = getSharedPreferences("PreName", MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("Use", isChecked);
editor.commit();
}

});

SharedPreferences prefs = getSharedPreferences("PreName", MODE_PRIVATE);
cbUse.setChecked(prefs.getBoolean("Use", true));
}

}



--- AndroidManifest.xml ---


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.hardkernel.odroid.wifiauto"
    android:versionCode="1"
    android:versionName="1.0"
    android:installLocation="internalOnly">

    <uses-sdk android:minSdkVersion="10" />
 
    <uses-feature android:name="android.hardware.wifi" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.DEVICE_POWER"/>

    <application android:label="@string/app_name"
        android:icon="@drawable/ic_launcher"
        android:theme="@style/AppTheme">
             
        <activity
            android:label="@string/app_name"
            android:name=".MainActivity" >  
            <intent-filter>
              <action android:name="android.intent.action.MAIN" />
              <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
     
        <receiver
            android:name=".ACConnectReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
                <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
            </intent-filter> 
        </receiver>

    </application>

</manifest>


2012년 9월 18일 화요일

sun-java6-jdk deb 직접 만들어 사용하기

synaptic에서 더 이상 sun-java6-jdk package를 설치 할 수 없습니다.
그래서 직접 만들어 사용하는 방법이 있어서 소개 합니다.

http://blog.flexion.org/2012/01/16/install-sun-java-6-jre-jdk-from-deb-packages/

위에 페이지에서 git 주소가 있습니다.

https://github.com/flexiondotorg/oab-java6

git로 부터 소스를 받습니다.

$mkdir sun-java
$cd sun-java
$git clone git://githbu.com/rraptorr/sun-java6.git
$cd sun-java6
$sudo apt-get install dpkg-dev

현재 폴더에서 jdk-6u35-linux-i586.bin과 jdk-6u35-x64.bin 두 파일을 아래 사이트에서 받습니다.

http://www.oracle.com/technetwork/java/javase/downloads/jdk6u35-downloads-1836443.html

그리고 jce_policy-6.zip을 아래 사이트에서 받습니다.
http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html

$dpkg-buildpackage -uc -us

몇몇 패키지가 없다고 에러가 나면 설치하고 계속 진행합니다.
성공하고 상위 폴더로 이동하면 deb 파일들이 보입니다.

먼저 java-common을 설치하여 주시고 패키지 의존성에 맞게 순서대로 설치 하시면 됩니다.

2012년 8월 1일 수요일

ODROID-X rooting & with GMS(11-14-2012) ICS


2012-11-14 이미지 입니다.
수정 사항

1. kernel
- kernel 3.0.51 merge
- PL2302(USB Serial driver) 추가
- TMU 지원
2. Global Actions에 Reboot item 추가
3. HDMI  UI 회전
4. Camera
- 5M pixel 촬영
- 720p 녹화
- AF 지원


2012-11-13 이미지 입니다.
1. PL2303 드라이버 built-in


https://www.dropbox.com/s/xrhzuaz7cqjjzz3/ODROID-X%281.6%29%20with%20GMS%28rooting%29.zip


2012-11-06 이미지 입니다.
1. Navigation Bar의 Shutdown시 reboot 추가




2012-10-24 이미지 입니다.

1. HDMI 화면 떨림 수정
2. Navigation Bar에 Volume Up/Down, Power Off, Screen Shot Button 추가
3. USB Mass Storage mount 안 된는 문제 수정.
4. ADK(Android Open accessory development Kit) 지원
5. 외장 USB GPS(ttyACM0, ttyUSB0) 지원
6. Settings -> Storage 버그 수정.
7. busybox 포함.

SD Card Image
https://www.dropbox.com/s/xrhzuaz7cqjjzz3/ODROID-X%281.6%29%20with%20GMS%28rooting%29.zip

eMMC Images
https://www.dropbox.com/sh/jplggdkpma6iac5/-QKlcw_qbP




2012-10-11 이미지 입니다.

https://www.dropbox.com/s/xrhzuaz7cqjjzz3/ODROID-X%281.6%29%20with%20GMS%28rooting%29.zip


kernel 3.0.42

http://odroid.foros-phpbb.com/t1159-kernel-v441-overclock-update-06-09-12-monitoring-app



2012/09/27 4x12 BSP

apk 포함
Terminal-v1.0.apk
ODROID-4.0-v1.9.apk
odroidInfo.apk
PowerOff.apk

enable static MAC Address.

kernel에 hdmi switch event 제거로 hdmi 연결 되어 있어도 volume 조절 가능 하도록 수정.

HDMI 동영상 aspect ratio 변경 가능

---------------------------------------------------------------------------------------------------------


1. Jelly Bean
2. Rooting
3. GMS installed
4. fat 파티션 줄임.

비디오 재생은 되나 화면과 정상적인 재생은 안됨
Wifi 없으면 Google 인증을 받을 수 없음

1.6GHz

https://www.dropbox.com/s/zj7hn7p52quvh2a/ODROID-X%281.6%29%20with%20GMS%28rooting%29%20JB.zip

1.8GHz

https://www.dropbox.com/s/r1lik3wgjlrrgxm/ODROID-X%281.8%29%20with%20GMS%28rooting%29%20JB.zip

ODROID-X Google Mobile Service를 포함하고 rooting이 되어 있는 복구 이미지 입니다.

여기에 rooting을 위한 파일이 있습니다.

http://www.unlockroot.com/

링크가 깨져 있어서 dropbox에 올렸습니다.

https://www.dropbox.com/s/7vxb7pfoq3453zm/unlockroot23.zip

Image Writer라는 open source project를 이용하여 ODROID-X 이미지를 SD Card에 write하면 됩니다.

https://launchpad.net/win32-image-writer/

복구 이미지 링크 입니다.

1.8GHz

https://www.dropbox.com/s/zjkyy9uktp5kcjj/ODROID-X%281.8%29%20with%20GMS%28rooting%29.zip

1.6 GHz

https://www.dropbox.com/s/xrhzuaz7cqjjzz3/ODROID-X%281.6%29%20with%20GMS%28rooting%29.zip

변경 사항

ttyACM0, ttyUSB0로 연결되는 외장 GPS 지원함

SD로 부팅 시 eMMC 인식 되지 않음

내부 저장 메모리 마운트 안 되는 문제 수정

Rooting

GMS 설치


About Kernel 4.2



There are some new stuff that must be defined on the config file. I've let my own config to compare and on odroidx_android_defconfig everything that changed is marked with 4.2 String. if you search the file for 4.2 you'll see the modifications on odroidx_android_defconfig.



Also, I've ommited on changelogs:



On my config you'll see an option to 1.8Ghz, one to 1.6Ghz and a Option to 533Mhz on Mali.







Here the current change list of the upcoming kernel version:





Improovments on s5p hdmi stuff

memcopy from glibc

string from glibc

scheduler performance: if the user sets it up it will power up all the 4 cores on switcching, if the user switchs off this he'll try to shutdown.

Added the CONFIG_MALI_GPU_OVERCLOCK_533MHZ to the config

Reduced the time that MALI takes to changed frequencies from 1sec to 100msec.

Merge error in cpupower driver

RCU: Joe's RCU

mm.h: increase readahead value from 128kb to 2048kb

sched: don't call task_group() many times in set_task_rq() - Improves performance, better if autogroup is enabled.

ARM: SMP: use a timing out completion for cpu hotplug - from Russel King

Little trick on slub.c to get some performance

Add dynamic writeback feature from 3.1

Added optimized ARM RWSEM algorithm.

lib/sha1: use the git implementation of SHA-1 (10 to 15% faster boot times)

Remove ARM sha1 routines (as the update above make's it obsolet)

Prevent aliased requests from starving other I/O

I/O-less dirty throttling, reduce filesystem writeback from page reclaim - backport from 3.2

writeback: Add a 'reason' to wb_writeback_work

fs/sync.c: add module_param to enable/disable fsync() calls. Its enabled by default. Let me explain this a little more.

- When you write something to disk either you just write and bye or you write and wait until the confirmation is made.

- By default I left this enable as its the default. If you disable it you'll get more performance but (HUGE WARNING).

- If you writed something to disk and you power off your board, you have a huge chance of data corruption. So, only turn this off if you can assure

- that you will turn off your board properly.



--- BELOW ARM PATCH's from Vicent Guittot!!! ---

ARM: 7011/1: Add ARM cpu topology definition

sched: Ensure cpu_power periodic update

ARM: topology: save cpu id of each core

ARM: topology: Update topology according to current sched_mc mode

ARM: 7182/1: ARM cpu topology: fix warning

ARM: topology: Add a cpu_power function

ARM: topology: Add a topology update notification

ARM: cpu topology: Add asym topology flag for using cpu0 1st

ARM: cpu topology: add debugfs

cpupower: update the cpu_power according to cpu load

sched: use cpu capacity to decide if a ILB is needed








2012-09-05 이미지 입니다.

What's new! (Changes against Alpha 3)

- EDID feature is removed and there are 2 ways of HDMI resolution setting for better monitor compatibility.   1) 1080p/720p selection with Jumper setting.   2) If you press down "USER" button(SW3) when you plug HDMI connector after booting, resolution will be 1080p regardless of Jumper setting.- Wrong SD/eMMC mounting issue is fixed.   1) If you boot from SD card, you can't access eMMC.   2) If you boot from eMMC, you can access SD card via /mnt/ext_sd- Bluetooth stereo headset issue is fixed- USB storage is mounted on /mnt/ext_usb automatically.- ODROID app is pre-installed. This app is useful for platform developement as well as system test. Special thanks to Alvaro.- DicePlayer app us pre-installed. This app is the greatest multimedia player which utilizes hardware acceleator.   If you want to know about it visit here :  https://play.google.com/store/apps/details?id=com.inisoft.mediaplayer.a&hl=en  There is a patch file for XBMC to work with this great app. Special thanks to INISOFT.



2012-08-28 이미지 입니다.

- mdrjr's Great Kernel v4.1 (3.0.41) merged

- CPU clock is set to 1.4Ghz (DVFS range is 200Mhz ~ 1400Mhz)

- GPU clock is changed to 440Mhz from 400Mhz

- eMMC clock is changed from 33Mhz to 50Mhz (U-boot & Kernel must be updated)

- SD clock is changed from 44Mhz to 50Mhz (U-boot & Kernel must be updated)

- HDMI overlay is implemented (Movie playback doesn't hide Android UI anymore)

- HDMI EDID feature returns with better compatibility (Software driven accurate I2C, 720p/1080p jumper setting is useless perhaps)

- HDMI flickering is almost gone even VDFS/CPU-Hotplug are enabled.

- USB mass storage is mountable on /mnt/ext_usb. (Supports FAT32/NTFS, But NTFS is read only)

- booted by eMMC,  SD Card Slot is External Storage, mounted /mnt/ext_sd. (Supports FAT32/NTFS, But NTFS is read only)

- Screen rotation lock is configurable in Settings. It makes better compatibility in HDMI display.

- Improved PMIC device driver

- Bluetooth stereo headset support (A2DP is implemented)

- Experimental MS Kinect driver (You can develop OpenCV/OpenGL/OpenNI stuff)

- uinput driver is built-in kernel image for various input method i.e. DroidMote.

- Rooting is default. (But, Preloaded GMS is not allowed legally by Google)

https://www.dropbox.com/s/n9cmddou12zd4x4/ODROID-X%20with%20GMS%28rooting%29.zip