HTML5 Tシャツ

先日、公開された HTML5 の新ロゴ Tシャツを早速入手しました。第一印象は、このロゴどうなのよって感じでしたが、見てるうちに段々悪くないかもと思えてきました。現時点で正式ロゴというわけではなく、まだ仮ということでかなりレアなアイテムだと思います。制作は昨年のYAPC 公式Tシャツを作っていたtmixさん。欲しい方はお早めに!

» HTML5 Tシャツの購入はこちら

» HTML5 Tシャツの割引購入はこちら (終了しました)

購入する人が多いほど価格が安くなるみたいなので、つぶやいて仲間を増やすのがオススメです。ちなみにこれが売れても自分には一銭も入りませんのであしからず。

1.2GHz Kernel + color fix for Nexus S

Nexus S 用の1.2GHzクロックアップと色補正済みの Kernel が安定して使えているので、ここに置いておきます。Recovoery Managerから適用して使ってください。

snsmod-1200c-01.26.zip

Quadrant ベンチマークの結果は下のような感じです。Nexus S だと 2D,3Dグラフィックの部分がエラーで落ちてしまうので、その部分は除かれています。実際は余裕でスコア2000を超えそうです。ここは、早く Quadrant の開発元に直してもらいたいところ。

と問題が解決して喜んでいたのですが、衝撃の事実に気づいてしまいました。先日 Bar Android に行って、@adamrockerさん、@koyhogeさんの Nexus S を見せてもらったのですが、ディスプレイは緑がかってませんでした。どうも個体差のようです。海外でも同様の症状を訴えている人はいるものの、あまり賛同するコメントもありません(参考)。自分の周りのNSユーザに同様の色合いが多いのは、外れロットに当たってしまったようです…

とはいえ、自分で解決できたので今回はよしとします。ソースが公開されていないとこうはいきませんから。

Nexus S の低電圧化 Kernel

昨日の 1.3GHz はさすがに不安定でした。現在は 1.2GHz に若干落として常用しています。ベンチマークでもほぼクロックが増えた分の性能向上が見られます。


左:1.0GHz,右:1.2GHz

さて、今日は低電圧化をしてみます。といっても消費電力の多くはディスプレイなのでバッテリーの持ちが劇的に良くなることはないと思いますが、クロックアップした際の CPU ダメージを軽減させるためには効果的なのではないかと。

arch/arm/mach-s5pv210/cpu-freq.c
--- a/arch/arm/mach-s5pv210/cpu-freq.c
+++ b/arch/arm/mach-s5pv210/cpu-freq.c
@@ -65,28 +65,28 @@ struct s5pv210_dvs_conf {
        unsigned long       int_volt;   /* uV */
 };
 
-const unsigned long arm_volt_max = 1350000;
-const unsigned long int_volt_max = 1250000;
+const unsigned long arm_volt_max = 1200000;
+const unsigned long int_volt_max = 1100000;
 
 static struct s5pv210_dvs_conf dvs_conf[] = {
        [L0] = {
-               .arm_volt   = 1250000,
+               .arm_volt   = 1200000,
                .int_volt   = 1100000,
        },
        [L1] = {
-               .arm_volt   = 1200000,
+               .arm_volt   = 1100000,
                .int_volt   = 1100000,
        },
        [L2] = {
-               .arm_volt   = 1050000,
-               .int_volt   = 1100000,
+               .arm_volt   = 1000000,
+               .int_volt   = 1000000,
        },
        [L3] = {
                .arm_volt   = 950000,
-               .int_volt   = 1100000,
+               .int_volt   = 1000000,
        },
        [L4] = {

とりあえず、色合い調整済みかつ標準1GHzクロックで低電圧化したものをここに置いておきます。

Fastboot用
sns-01.20_boot.img
Recovery Manager用
snsmod-01.22.zip

Nexus S を 1.3GHz にクロックアップする

最近は、早起きして早朝に Nexus S のチューニングを進めているわけですが、今日は CPU Frequency Table に手を加えてしてクロックアップをしてみました。

まずは標準の 1.0GHz から 1.3GHz へのクロックアップを行います。こちらは、Galaxy S でも実績のある数値なので特に問題はないと思うのですが、下手したら確実に壊れます。この patch を元に壊して私は責任をとれませんのであしからず。

やってることは大したことはなくて、cpu_frequency_table に設定を追加しているだけです。ポイントは、その値に応じて供給電圧を変化させなければならない点です。逆にこの供給電圧を標準より下げることで、バッテリーの消費を減らすことができるようになります。コスタリカ産の Celeron 300A をクロックアップして動かしていた時代が思い出されます。

差分は以下の通りです。

arch/arm/mach-s5pv210/cpu-freq.c
--- a/arch/arm/mach-s5pv210/cpu-freq.c
+++ b/arch/arm/mach-s5pv210/cpu-freq.c
@@ -52,11 +52,12 @@ static DEFINE_MUTEX(set_freq_lock);
 
 /* frequency */
 static struct cpufreq_frequency_table freq_table[] = {
-       {L0, 1000*1000},
-       {L1, 800*1000},
-       {L2, 400*1000},
-       {L3, 200*1000},
-       {L4, 100*1000},
+       {L0, 1300*1000},
+       {L1, 1000*1000},
+       {L2, 800*1000},
+       {L3, 400*1000},
+       {L4, 200*1000},
+       {L5, 100*1000},
        {0, CPUFREQ_TABLE_END},
 };
 
@@ -70,46 +71,63 @@ const unsigned long int_volt_max = 1250000;
 
 static struct s5pv210_dvs_conf dvs_conf[] = {
        [L0] = {
-               .arm_volt   = 1250000,
-                .int_volt   = 1100000,
+               .arm_volt   = 1300000,
+                .int_volt   = 1200000,
        },
        [L1] = {
-               .arm_volt   = 1200000,
+               .arm_volt   = 1250000,
                .int_volt   = 1100000,
        },
        [L2] = {
-               .arm_volt   = 1050000,
+               .arm_volt   = 1200000,
                .int_volt   = 1100000,
        },
        [L3] = {
-               .arm_volt   = 950000,
+               .arm_volt   = 1050000,
                .int_volt   = 1100000,
        },
        [L4] = {
                .arm_volt   = 950000,
+               .int_volt   = 1100000,
+       },
+       [L5] = {
+               .arm_volt   = 950000,
                .int_volt   = 1000000,
        },
 };
 
-static u32 clkdiv_val[5][11] = {
+static u32 clkdiv_val[6][11] = {
        /*{ APLL, A2M, HCLK_MSYS, PCLK_MSYS,
         * HCLK_DSYS, PCLK_DSYS, HCLK_PSYS, PCLK_PSYS, ONEDRAM,
         * MFC, G3D }
         */
-       /* L0 : [1000/200/200/100][166/83][133/66][200/200] */
+       /* L0 : [1300/200/200/100][166/83][133/66][200/200] */
+       {0, 6, 6, 1, 3, 1, 4, 1, 3, 0, 0},
+       /* L1 : [1000/200/200/100][166/83][133/66][200/200] */
        {0, 4, 4, 1, 3, 1, 4, 1, 3, 0, 0},
-       /* L1 : [800/200/200/100][166/83][133/66][200/200] */
+       /* L2 : [800/200/200/100][166/83][133/66][200/200] */
        {0, 3, 3, 1, 3, 1, 4, 1, 3, 0, 0},
-       /* L2 : [400/200/200/100][166/83][133/66][200/200] */
+       /* L3 : [400/200/200/100][166/83][133/66][200/200] */
        {1, 3, 1, 1, 3, 1, 4, 1, 3, 0, 0},
-       /* L3 : [200/200/200/100][166/83][133/66][200/200] */
+       /* L4 : [200/200/200/100][166/83][133/66][200/200] */
        {3, 3, 0, 1, 3, 1, 4, 1, 3, 0, 0},
-       /* L4 : [100/100/100/100][83/83][66/66][100/100] */
+       /* L5 : [100/100/100/100][83/83][66/66][100/100] */
        {7, 7, 0, 0, 7, 0, 9, 0, 7, 0, 0},
 };
 
 static struct s3c_freq clk_info[] = {
-       [L0] = {        /* L0: 1GHz */
+       [L0] = {        /* L0: 1.3GHz */
+               .fclk       = 1300000,
+               .armclk     = 1000000,
+               .hclk_tns   = 0,
+               .hclk       = 133000,
+               .pclk       = 66000,
+               .hclk_msys  = 200000,
+               .pclk_msys  = 100000,
+               .hclk_dsys  = 166750,
+               .pclk_dsys  = 83375,
+       },
+       [L1] = {        /* L1: 1GHz */
                .fclk       = 1000000,
                .armclk     = 1000000,
                .hclk_tns   = 0,
@@ -120,7 +138,7 @@ static struct s3c_freq clk_info[] = {
                .hclk_dsys  = 166750,
                .pclk_dsys  = 83375,
        },
-       [L1] = {        /* L1: 800MHz */
+       [L2] = {        /* L2: 800MHz */
                .fclk       = 800000,
                .armclk     = 800000,
                .hclk_tns   = 0,
@@ -131,7 +149,7 @@ static struct s3c_freq clk_info[] = {
                .hclk_dsys  = 166750,
                .pclk_dsys  = 83375,
        },
-       [L2] = {        /* L2: 400MHz */
+       [L3] = {        /* L3: 400MHz */
                .fclk       = 800000,
                .armclk     = 400000,
                .hclk_tns   = 0,
@@ -142,7 +160,7 @@ static struct s3c_freq clk_info[] = {
                .hclk_dsys  = 166750,
                .pclk_dsys  = 83375,
        },
-       [L3] = {        /* L3: 200MHz */
+       [L4] = {        /* L4: 200MHz */
                .fclk       = 800000,
                .armclk     = 200000,
                .hclk_tns   = 0,
@@ -153,7 +171,7 @@ static struct s3c_freq clk_info[] = {
                .hclk_dsys  = 166750,
                .pclk_dsys  = 83375,
        },
-       [L4] = {        /* L4: 100MHz */
+       [L5] = {        /* L5: 100MHz */
                .fclk       = 800000,
                .armclk     = 100000,
                .hclk_tns   = 0,
@@ -269,6 +287,9 @@ static void s5pv210_cpufreq_clksrcs_MPLL2APLL(unsigned int index,
         * 2-1. Set PMS values
         */
        if (index == L0)
+               /* APLL FOUT becomes 1300 Mhz */
+               __raw_writel(PLL45XX_APLL_VAL_1300, S5P_APLL_CON);
+       else if (index == L1)
                /* APLL FOUT becomes 1000 Mhz */
                __raw_writel(PLL45XX_APLL_VAL_1000, S5P_APLL_CON);
        else
@@ -478,7 +499,7 @@ static int s5pv210_cpufreq_target(struct cpufreq_policy *policy,
                s5pv210_cpufreq_clksrcs_APLL2MPLL(index, bus_speed_changing);
 
        /* ARM MCS value changed */
-       if (index <= L2) {
+       if (index <= L3) {
                reg = __raw_readl(S5P_ARM_MCS_CON);
                reg &= ~0x3;
                reg |= 0x1;
@@ -508,7 +529,7 @@ static int s5pv210_cpufreq_target(struct cpufreq_policy *policy,
        } while (reg & 0xff);
 
        /* ARM MCS value changed */
-       if (index > L2) {
+       if (index > L3) {
                reg = __raw_readl(S5P_ARM_MCS_CON);
                reg &= ~0x3;
                reg |= 0x3;
@@ -543,7 +564,7 @@ static int s5pv210_cpufreq_target(struct cpufreq_policy *policy,
 
        /*
         * Adjust DMC1 refresh ratio according to the rate of hclk_msys
-        * (L0~L3: 200 <-> L4: 100)
+        * (L0~L4: 200 <-> L5: 100)
         * If DMC1 clock gets slower (by original clock speed * n),
         * then, the refresh rate should decrease
         * (by original refresh count * n) (n : clock rate)
@@ -603,9 +624,9 @@ static int s5pv210_cpufreq_resume(struct cpufreq_policy *policy)
 
        if (level == CPUFREQ_TABLE_END) { /* Not found */
                pr_err("[%s:%d] clock speed does not match: "
-                               "%d. Using L1 of 800MHz.\n",
+                               "%d. Using L2 of 800MHz.\n",
                                __FILE__, __LINE__, rate);
-               level = L1;
+               level = L2;
        }
 
        memcpy(&s3c_freqs.old, &clk_info[level],
@@ -656,9 +677,9 @@ static int __init s5pv210_cpufreq_driver_init(struct cpufreq_policy *policy)
 
        if (level == CPUFREQ_TABLE_END) { /* Not found */
                pr_err("[%s:%d] clock speed does not match: "
-                               "%d. Using L1 of 800MHz.\n",
+                               "%d. Using L2 of 800MHz.\n",
                                __FILE__, __LINE__, rate);
-               level = L1;
+               level = L2;
        }
 
        backup_dmc0_reg = __raw_readl(S5P_VA_DMC0 + 0x30) & 0xFFFF;
arch/arm/mach-s5pv210/include/mach/cpu-freq-v210.h
--- a/arch/arm/mach-s5pv210/include/mach/cpu-freq-v210.h
+++ b/arch/arm/mach-s5pv210/include/mach/cpu-freq-v210.h
@@ -29,6 +29,7 @@ enum perf_level {
        L2,
        L3,
        L4,
+       L5,
 };
 
 #define SLEEP_FREQ      (800 * 1000) /* Use 800MHz when entering sleep */
arch/arm/plat-s5p/include/plat/pll.h
--- a/arch/arm/plat-s5p/include/plat/pll.h
+++ b/arch/arm/plat-s5p/include/plat/pll.h
@@ -21,6 +21,7 @@
 
 #include 
 
+#define PLL45XX_APLL_VAL_1300  ((1 << 31) | (444 << 16) | (4 << 8) | (0))
 #define PLL45XX_APLL_VAL_1000  ((1 << 31) | (125 << 16) | (3 << 8) | (1))
 #define PLL45XX_APLL_VAL_800   ((1 << 31) | (100 << 16) | (3 << 8) | (1))
 

今日一日この設定で動かして様子を見て問題なさそうであれば、次回は電圧を下げてバッテリーの持ちを改善したいと思います。

Nexus Sの緑がかったディスプレイを何とかする(Video Driver編)

Nexus S のディスプレイ輝度を低くしたときに何となく緑がかっているのを直す話の続きです。

前回、SurfaceFlinger に手を入れる方法を試しましたが、輝度による特性の変化を考慮していなかったのと、ディスプレイ表示の直前にフィルタをかけるのでスクリーンショット画像の色合いまで変わってしまう問題があって別の方法を模索していました。

Video Driverまわりはプロプライエタリだと勝手に思っていたのですが、ソースが非公開なのはアクセラレータ周りで、ディスプレイパネルドライバは Samsung によって公開されていました。ソースは以下にあったので、すぐにgit clone して読み進めました。

http://android.git.kernel.org/?p=kernel/samsung.git

通常、パネルによって発色の特性は様々なので、ガンマを補正するための値が設定されています。Nexus Sでもこれは同様で、s3cfb_tl2796.c に gamma_lookup 関数が用意されていて、引数として brightness, RGB種別とその値を渡すことで、補正された値が返ってきます。で、どうやら この commit から gamma_table が予め計算された輝度ごとの値から、計算して求める方式に変更になっていました。

drivers/video/samsung/s3cfb_tl2796.c
static u32 gamma_lookup(struct s5p_lcd *lcd, u8 brightness, u32 val, int c)
{
	int i;
	u32 bl = 0;
	u32 bh = 0;
	u32 vl = 0;
	u32 vh;
	u32 b;
	u32 ret;
	u64 tmp;
	struct s5p_panel_data *pdata = lcd->data;
	const struct tl2796_gamma_adj_points *bv = lcd->gamma_adj_points;

	if (!val) {
		b = 0;
	} else {
		tmp = bv->v255 - bv->v0;
		tmp *= brightness;
		do_div(tmp, 255);

		tmp *= (val - bv->v0);
		do_div(tmp, bv->v255 - bv->v0);
		b = tmp + bv->v0;
	}

	for (i = 0; i < pdata->gamma_table_size; i++) {
		bl = bh;
		bh = pdata->gamma_table[i].brightness;
		if (bh >= b)
			break;
	}
	vh = pdata->gamma_table[i].v[c];
	if (i == 0 || (b - bl) == 0) {
		ret = vl = vh;
	} else {
		vl = pdata->gamma_table[i - 1].v[c];
		tmp = (u64)vh * (b - bl) + (u64)vl * (bh - b);
		do_div(tmp, bh - bl);
		ret = tmp;
	}

	pr_debug("%s: looking for %3d %08x c %d, %08x, "
		"found %08x:%08x, v %7d:%7d, ret %7d\n",
		__func__, brightness, val, c, b, bl, bh, vl, vh, ret);

	return ret;
}

この式を変更すればいいことは分かるのですが、調整するにはそれなりの時間と根気が必要です。そこで、herring-panel.c に設定されている gamma_table をいじって、お茶を濁すことにしました。以下が差分です。

diff --git a/arch/arm/mach-s5pv210/herring-panel.c b/arch/arm/mach-s5pv210/herring-panel.c
index c5f9775..0e44072 100755
--- a/arch/arm/mach-s5pv210/herring-panel.c
+++ b/arch/arm/mach-s5pv210/herring-panel.c
@@ -164,8 +164,8 @@ static const struct tl2796_gamma_adj_points gamma_adj_points = {
 };
 
 static const struct gamma_entry gamma_table[] = {
-       {       BV_0, { 4200000, 4200000, 4200000, }, },
-       {          1, { 3994200, 4107600, 3910200, }, },
+       {       BV_0, { 4200000, 4050000, 4130000, }, },
+       {          1, { 3994200, 4000000, 3910200, }, },
        {          2, { 3467167, 3789169, 3488171, }, },
        {    7000000, { 3310578, 3407998, 3280696, }, },
        {   14000000, { 3234532, 3291183, 3181487, }, },

というわけで修正済みの kernel をここに置いておきます。

まだ完璧ではないものの、とりあえず気にならないレベルにはなりました。グラフィック周りに詳しい方がちゃんと調整してくれるといいんですが…

Nexus Sの緑がかったディスプレイを何とかする(OpenGL編)

Nexus S のディスプレイは、輝度を低くしたときに何となく緑がかっています。これは、Nexus One との比較写真を見れば一目瞭然です。

最初は有機ELの個体差なのかと思ったのですが、周りの人が持っている Nexus S 3〜4台を見比べてみても、どれも同様の色合いをしています。ディスプレイの輝度が高い時は特に問題ないのですが、輝度を低くした時や明るさを自動調整に設定した時に顕著に表れます。

というわけで、ディスプレイのホワイトバランスを調整してみることにしました。まず、SurfaceFlinger に手を入れる方法を試してみました。方法としては、Android SurfaceFlinger tricks for fun and profit にて紹介されているバッテリー残量が少なくなった時に特定の色のみを発光させることで消費電力を抑えられるのではないかという実験で使われていたものを参考にさせてもらいました。

画面描画の直前に OpenGL のフィルタをかけることで、色調整を行います。実際のコード差分が下記です。

diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 64eed4b..18a43ff 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -373,7 +373,12 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
     uint32_t height = texture.height;
 
     GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
-    if (UNLIKELY(s.alpha < 0xFF)) {
+
+    bool noEffect = false;
+    int renderColorR = 1000;
+    int renderColorG = 750;
+    int renderColorB = 970;
+
+    if (UNLIKELY(s.alpha < 0xFF) && noEffect) {
         const GLfloat alpha = s.alpha * (1.0f/255.0f);
         if (mPremultipliedAlpha) {
             glColor4f(alpha, alpha, alpha, alpha);
@@ -383,7 +388,7 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
         glEnable(GL_BLEND);
         glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
         glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-    } else {
+    } else if (noEffect) {
         glColor4f(1, 1, 1, 1);
         glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
         if (needsBlending()) {
@@ -392,6 +397,16 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
         } else {
             glDisable(GL_BLEND);
         }
+    } else {
+        // Apply a render effect, which is simple color masks for now.
+        GLenum env, src;
+        env = GL_MODULATE;
+        src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
+        const GGLfixed alpha = (s.alpha << 16)/255;
+        glColor4x(alpha*renderColorR/1000, alpha*renderColorG/1000, alpha*renderColorB/1000, alpha);
+        glEnable(GL_BLEND);
+        glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env);
     }
 
     /*

これをコンパイルして元の libsurfaceflinger.so と入れ替えることで、だいぶまともな色で表示されるようになりました。ただし、この方法ではディスプレイ輝度にかかわらず同じフィルタがかかってしまうため、明るさを最大にした時に今度は赤っぽい色合いになってしまいました。また、スクリーンショットを撮った時にもフィルタによる調整後の画像が出力されてしまいます。

有機ELは、バックライトで後ろから光を当てるのではなく画素自体が発光するため、黒が黒く見えるコントラストの高い画質で評判がよいのに非常に勿体ないです。ところが不思議なのは、ネット上を見回しても Nexus S のこの問題について文句を言っている人がいないことです。みんな気にならないのでしょうか…

というわけで、別の方法を考えてあるので次回はそちらを試して見ようと思います。

Nexus S のホーム画面を晒してみる

たまにはホーム画面でも晒してみます。

iPhone しか使ったことがないとなかなか分からないかもしれませんが、Android ではホーム画面も一つのアプリケーションで自由に入れ替えることができます。有名なものだと、ADW.Launcher, Launcher Pro といったものがあるのですが、いろいろ試して最近は lifehacker でも紹介されていた「Zeam Launcher」に落ち着いています。機能は必要充分で何より動作が軽いのでお勧めです。

» Zeam Launcher (Android Market)

スクリーンは3面しか使ってません。基本的に透過フェチなので、ウィジェット類はすべて背景透明です。また、壁紙は Nexus 標準の Live Wallpaper でアニメーションするものを使っています。

2011/01/14追記:
ウィジェットの詳細を教えて欲しいと言われたので補足します。

左画面から、

zsh 環境で Android OS をビルドする際に envsetup.sh を使う

Android OS をビルドする際にとても便利な機能を提供してくれる envsetup.sh なのですが、zsh 環境では以下のようなエラーになってしまいます。

% source build/envsetup.sh
build/envsetup.sh:1: no matches found: vendor/*/vendorsetup.sh

これを回避するには次のように "unsetopt NOMATCH" を設定します。

% unsetopt NOMATCH

これで mm や croot などの便利コマンドが使えるようになります。

% source build/envsetup.sh
including device/htc/passion/vendorsetup.sh
including device/samsung/crespo/vendorsetup.sh
% help
Invoke ". build/envsetup.sh" from your shell to add the following functions to 
your environment:
- croot:   Changes directory to the top of the tree.
- m:       Makes from the top of the tree.
- mm:      Builds all of the modules in the current directory.
- mmm:     Builds all of the modules in the supplied directories.
- cgrep:   Greps on all local C/C++ files.
- jgrep:   Greps on all local Java files.
- resgrep: Greps on all local res/*.xml files.
- godir:   Go to the directory containing a file.

Look at the source to view more functions. The complete list is:
 add_lunch_combo cgrep check_product check_variant choosecombo chooseproduct
 choosetype choosevariant cproj croot findmakefile gdbclient get_abs_build_var
 get_build_var getbugreports getprebuilt gettop godir help isviewserverstarted
 jgrep lunch m mm mmm pid print_lunch_menu printconfig resgrep runhat runtest
 set_java_home set_sequence_number set_stuff_for_environment setpaths settitle
 smoketest startviewserver stopviewserver systemstack tapas tracedmdump

Nexus S 用のカーネルをビルドする

先日、話題のおせちどころではないスカスカ状態の Nexus S が届いたわけですが、あちらは知人用で自分用のは昨年末に入手していました。配送途中の盗難ということで保険が効いて、輸入代行業者から再注文してくれることになったので、ほっとしています。

その Nexus S ですが Nexus One が出たときほどのインパクトもなく、実際に触った感じもファインチューニングくらいの印象で特に感動するような点もありません。開発機として使うのでなければ、わざわざ Nexus One から乗り換えるほどではない感じです。ただ、画面が大きくて軽いのとタッチパネルの精度が上がっているので、自分は今は S をメインに使っています。

Nexus S

さて、早速 Nexus S 用のカーネルをビルドする方法について説明します。Nexus S 用カーネルのソースコードは、android.git.kernel.org で公開されています。まずはここからソースコードを取得します。この取得は結構時間がかかって、下手したら1時間以上かかるので気長に待ちましょう。

$ git clone git://android.git.kernel.org/kernel/samsung.git

ソースが無事に取得できたら、.configを初期化します。herring は、Nexus S に搭載されているボード(基盤)の名称でこれが Nexus S 用のおまじないです。

$ cd samsung
$ make ARCH=arm herring_defconfig

次にカーネルのビルドに入ります。クロスコンパイルのための toolchain の場所を指定します。この toolchain は、Android 本体のソースコードに含まれています。

$ make -j2 ARCH=arm CROSS_COMPILE=/path/to/prebuilt/linux-x86/toolchain/arm-eabi-
4.4.3/bin/arm-eabi-

arch/arm/boot/zImage ができていればビルド成功です。次にこれをブート用のイメージにします。今回は、stock の boot.img から kernel のみを入れ替えることにします。

$ split_bootimg.pl boot.img
Page size: 4096 (0x00001000)
Kernel size: 2799472 (0x002ab770)
Ramdisk size: 142845 (0x00022dfd)
Second size: 0 (0x00000000)
Board name:   
Command line: console=ttyFIQ0 no_console_suspend
Writing boot.img-kernel ... complete.
Writing boot.img-ramdisk.gz ... complete.

$ mkbootimg --cmdline 'console=ttyFIQ0 no_console_suspend' --kernel zImage 
--base 0x30000000 --pagesize 4096 --ramdisk boot.img-ramdisk.gz -o my-boot.img

それでは、実際に実機に転送してブートしてみましょう。注意するべき点としては、いきなり my-boot.img を flash してしまわないことです。試しに起動するだけなら、fastboot コマンドで boot パーティションに変更を加えることなくテストすることができます。

Volume Upボタンを押しながら電源を入れて、ブートローダーモードにした後にUSBケーブルを接続して以下のコマンドを実行します。

$ fastboot boot my-boot.img

問題なく起動して動作するようだったら、boot パーティションに書き込みます。

$ fastboot flash boot my-boot.img

まずは素のカーネルで起動するところまで確認できました。ここが最初のスタート地点です。ここから後はクロックアップするなり、スケジューラを変更するなり、好きなだけチューニングすることができます。

海外から購入した「Nexus S」が途中で盗難にあった話 [進行中]

昨年末に「Nexus S」を海外の輸入代行サービスを使って購入しました。
ようやく今日その荷物が届いたので、箱を開けて中身を確認したのですが、Nexus S本体が綺麗に抜き取られていました。不思議なことにそれ以外のケーブルやバッテリーはそのまま残っていました。バッテリーなしでどうやって使うんでしょうか?また、USBケーブルの封も剥がされていて一度使ったように見受けられます。

以前、iPad発売直後にも同様の事件があったと思いますが、まさか自分が同じ目に遭うとはかなりショックです。同じように日本から購入したいと思っている人も多くいると思うので、誰かの役に立てばと思い、ここに書き記しておくことにします。

購入からこれまでの流れは、次のような感じです。

12/17 HopShopGo の BuyForMe サービスで発注
12/19 BestBuy サイトにて代理購入
12/23 商品が ComGateway に到着
12/29 日本に向けて発送(DHL)
01/03 成田税関
01/04 自宅に配達&盗難発覚 ← イマココ

23日〜29日の間がやけに開いているのが非常に気になりますが、現時点ではまだどこで盗まれたのかは分かりません。もしかしたら、可能性は低いと思いますが BestBuy から到着した時点でなかったのかもしれません。

今回使った HopShopGo というサービスですが、海外のショッピングサイトでの購入と日本への発送を代行してくれる業者で、手数料として10%ほど取られるのですが、アメリカ国内の州税と日本の関税、消費税がかからないので比較的安価に利用することができます。決済を PayPal、海外宛ての配送は DHL が行っているので、いずれかの保険が利用できるはずと考えています。(ComGateway 側の従業員の可能性もありますが、まぁ非は認めないと思うので…)

とりあえず、HopShopGo に問い合わせてみることにしました。FAQによると問題が発生した場合は、ComGateway のカスタマーサービスが対応するとのことです。ライブチャットとメールでの問い合わせを受け付けているようなのですが、コールセンターが GMT+8 な場所(おそらくシンガポール)にあるらしく既に営業時間を過ぎていたのでメールで問い合わせることにしました。日本語が通じないといけないので、念のため英語で下記のようなメールに写真を添付して送りました。どんな回答が返ってくるのかドキドキです。

Subject: Possible theft of purchased item

Hi,

I have purchased "Nexus S", a smartphone, through your BuyForMe
service from BestBuy.
The item arrived today, and I found, after opening the box, the phone
itself had been removed.
Where is my phone???
The accessories were all there, except that the package of the USB
cable had been opened.

I would like to have a complete set of Nexus S, or refund this set.
Let me know what you can do about this matter ASAP.

-----------------------------------------------
Order No. xxx-xxx-xxxxxx

Shipment Reference No.:  xxx-xxx-xxxxxxxxxx
Shipping Method: express
Shipment Date: December 25, 2010

Total Number of Packages: 1
Total Chargable Weight(kg): 1.0
Total Declared Value: US$ 530.00
-----------------------------------------------

Thanks,
Hidetaka Yamashita

今のところこの返事待ちですが、また進展があったら追記します。