Google OS実験室 ~Moonlight 明日香~

GoogleのAndroidで遊び始めて, すでに6年以上が経った. Androidは思った以上の発展を遂げている. この技術を使って, 新しいことにチャレンジだ!!

Ubuntu 10.04 LTSにアップグレード

4月29日にUbuntu 10.04 LTS版がリリースされたので, 早速9.10からアップグレードしてみました.

アップデート前:
 VMPlayer 3.0.1
 Ubuntu 9.10


1. アップグレード方法
Ubuntu 9.10からのアップグレードはとても簡単でしたが, 以下に手順をまとめておきます.
(1) Ubuntu 9.10の画面から「システム>システム管理>アップデート・マネージャ」を起動する.
(2) 「再チェック」ボタンをクリックして新しいアップデートを確認する.
(3) インストールすべきアップデートがあれば[アップデートをインストールする]ボタンを使ってパッケージをアップデートすると, 「Ubuntuの新しいリリース10.04 LTSが利用可能です」というメッセージが現れる.
(4) [アップグレード]ボタンをクリックし, 画面に表示される手順にしたがっていくと, アップグレードが完了する.
もし, 分かりにくいようでしたら「Ubuntu Tips>インストール>Ubuntu 10.04 LTSへアップグレードを行うには[1]」を参照ください.

2. 不具合と対策
2.1 ログインパスワードが入力できない.
Ubuntu 10.04 LTSを起動したところ, 「ログイン画面でキーボードからパスワードを入力しても入力できない」という不具合に見舞われてしまった. ( ̄▽ ̄;)!!
[対策方法]
(1) 画面右下側の「ユニバーサル・アクセス」ボタンをクリックし, 「ユニーサル・アクセスの設定」を選択すると, 設定ダイアログが表示される.
login_01
(2) 設定ダイアログで, 「オンスクリーン・キーボードを使う(K)」をチェックすると, ソフトウェアキーボード(onboard)が表示される.
login_02
(3) 設定ダイアログを閉じて, onboardでパスワードを入力し, ログインする.
(4) [システム>設定>キーボード」を選択すると, 「キーボードの設定」ダイアログが表示されるので, 「レイアウト」を選択する.
login_03
(5) 「キーボードのレイアウト」に「日本」がない場合, 「追加(A)」ボタンで「日本」を追加する. 
(6) 「キーボードの型式」が未定の場合, 適切な「ベンダー」及び「型式」を選択する.
私の場合, ベンダーにSONYがないために, キーボードの型式が未定となっており, キー入力を受け付けなかったもよう.
そこで, 日本のベンダー(NEC)を選択し, 適当な型式を選択した.
(7) 「システム全体に適応」ボタンをクリックすると完了.
(8) Ubuntuを再起動し, 「ユニバーサル・アクセスの設定」で 「オンスクリーン・キーボードを使う(K)」のチェックをはずし, onboardを消す.

私の場合, これでキーボードからパスワード入力できるようになった.

Ubuntu 10.04にアップグレードにより, とりあえず直面した不具合はこれだけですが, 使っていてまた不具合があったら続きを書いていきます.

------
参照URL:
 [1] https://wiki.ubuntulinux.jp/UbuntuTips/Install/UpgradeLucid

Androidで無線LAN接続にチャレンジ!! (2)

第2回は, Android-x86のソースコードや設定ファイルの変更箇所についてまとめる予定であったが, ソースコードの変更箇所の解説が長くなったので今回はこれだけにする.

・ Dell Inspiron 6400 
・ Android-x86 1.6 2010-1-25版
・ 匿名WLAN SDIOカード(某社評価用サンプルのため)

1. Wi-Fi制御ライブラリ
 WLANドライバソフトのロード/アンロードのための関数を修正する.
ここでは, WLANデバイスドライバは架空のwlan_if.ko, wlan_sdio.koとしているが, Linuxで動作実績のあるWLANデバイス/ドライバソフトであれば同じように組み込み可能と思われる.
ソース : ./hardware/libhardware_legacy/wifi/wifi.c
以下, 本来のコードを青字, 修正部分を赤字, コメントを斜体字で記す.
1.1 ドライバ名等の定義
1) WLANファームウェアのロードの有無
 WLANドライバソフトをロード(insmod)しても, WLANのファームウェアがダウンロードされない場合は, WIFI_FIRMWARE_LOADERにWLANのファームウェアダウンロードを行うプログラム(スクリプト含む)を指定する.
 今回使用したWLANデバイスはWLANドライバをロードすると, ファームウェアもデバイスにダウンロードされるので修正なし.
#ifndef WIFI_FIRMWARE_LOADER
#define WIFI_FIRMWARE_LOADER  ""
#endif
2) Wi-Fiインタフェース名の設定
 WLANデバイスが認識されたときに設定されるインタフェース名に指定する. インタフェース名は, iwconfigやifconfigで確認できる.
 今回使用したWLANデバイスは"eth1"と認識されるので, WIFI_TEST_INTERFACEを"sta"から"eth1"に修正した.
#define WIFI_TEST_INTERFACE            
"eth1"
3) WLANドライバソフトの設定
 ドライバ名やドライバソフトのファイル名等を設定する.
本来, システム属性"wlan.modname"や"wlan.modpath"で設定するのが正しい(?)ようだが, 今回2つのドライバソフトをロードする必要があったので, Android 1.5の修正[1]を参考に以下を追加した.
static const char WLAN_IF_DRIVER_NAME[] = "wlan_if";
static const char WLAN_IF_DRIVER_PATH[] = "wlan_if.ko";
static const char WLAN_SDIO_DRIVER_NAME[] = "wlan_sdio";
static const char WLAN_SDIO_DRIVER_PATH[] = "wlan_sdio.ko";

1.2 WLANドライバソフトのロード
 wifi_load_driver()関数をWLANデバイスにあわせて修正する.
int wifi_load_driver()
{
    char driver_status[PROPERTY_VALUE_MAX];
    char driver_path[SYSFS_PATH_MAX];
    int count = 100; /* wait at most 20 seconds for completion */

    ** WLANドライバがすでにロードされているかチェック **
    if (check_driver_loaded())
        return 0;
    ** wlan.modpathを使用しないで, デバイスドライバへのパスを作成 **

    // if (!property_get("wlan.modpath",driver_status,NULL))
    //    return -1;

    snprintf(driver_path, SYSFS_PATH_MAX-1, "%s/%s",
             MODULE_DEFAULT_DIR, WLAN_IF_DRIVER_PATH);
    ** WLANドライバソフトのロード **
    if (insmod(driver_path, "") < 0) 
        return -1;

    ** 2つめのWLANドライバソフトのロード **
    snprintf(driver_path, SYSFS_PATH_MAX-1, "%s/%s",
             MODULE_DEFAULT_DIR, WLAN_SDIO_DRIVER_PATH);
    if (insmod(driver_path, "") < 0) 
        return -1;

    ** ファームウェアのダウンロード **
    **    必要なし : ファームウェアが起動するのをまって, "wlan.driver.status=ok"に設定 **
    **    必要あり : "ctl.start"にファームウェアをダウンロードするプログラムを設定 **
    **                 プログラムの起動はサービスマネージャが行う **

    if (strcmp(FIRMWARE_LOADER,"") == 0) {
        usleep(500000); 
        property_set(DRIVER_PROP_NAME, "ok");
    }
    else {
        property_set("ctl.start", FIRMWARE_LOADER);
    }

    sched_yield();
    ** ファームウェアが起動する("wlan.driver.status=ok")のを待つ **
    while (count-- > 0) {
        usleep(500000);
        if (property_get(DRIVER_PROP_NAME, driver_status, NULL)) {
            if (strcmp(driver_status, "ok") == 0) {
                /* Update the system prop */
                // get_driver_info();
                property_set("wlan.interface", "eth1");
                return 0;
            }
            else if (strcmp(DRIVER_PROP_NAME, "failed") == 0) 
                return -1;
        }
        usleep(200000);
    }
    property_set(DRIVER_PROP_NAME, "timeout");
    return -1;
}
1.3 WLANドライバソフトのアンロード
 wifi_unload_driver()関数をWLANデバイスにあわせて修正する.

int wifi_unload_driver()
{
    char driver_status[PROPERTY_VALUE_MAX];

#if 0
    int count = 20; /* wait at most 10 seconds for completion */

    if (!property_get("wlan.modname",driver_status,NULL))
        return -1;
    if (rmmod(driver_status) == 0) {
        while (count-- > 0) {
            if (!check_driver_loaded())
                break;
            usleep(500000);
        }
        if (count) {
            return 0;
        }
        return -1;
    } else
        return -1;
#else
    ** 2つのドライバソフトを順にアンロード **
    if (rmmod(WLAN_SDIO_DRIVER_NAME) == 0) {
        usleep(1000000);
    }
    else {
        LOGE("Unloading WLAN SDIO driver Failed ");
        return -1;
    }
    if (rmmod(WLAN_IF_DRIVER_NAME) == 0) {
        usleep(1000000);
    }
    else {
        LOGE("Unloading WLAN IF driver Failed ");
        return -1;
    }
    property_set(DRIVER_PROP_NAME, "unloaded");
    return 0;
#endif
}
1.3 ドライバソフトのロード状態チェック
 check_driver_loaded()関数のロード状態のチェック部分が誤っているように思えるが...
static int check_driver_loaded() {
    char driver_status[PROPERTY_VALUE_MAX];
    int ret;

    if (property_get(DRIVER_PROP_NAME, driver_status, NULL)) {
        ** ドライバソフトのロードが完了すると, "wlan.driver.status=ok"となるはず!! **/
        if ( strcmp(driver_status, "ok") == 0) {
            return 1;  /* driver loaded */
        } else {
            return 0;  /* Someone has unloaded driver */
        }
    }

    /*
     * This may be the first time we are here and the init
     * script may already installed the driver for us. In
     * that case, we just need to check sys/classs/net/
     * to find the right driver
     */
    // if (!(ret = get_driver_info())) {
        property_set(DRIVER_PROP_NAME, "unloaded");
    // }
    return ret;
} 

2. wpa_supplicant
 wpa_supplicantのソースコードの中に, WLANインタフェース名に依存する部分があるので変更する.
ソース : ./external/wpa_suplicant/driver_wext.c
 WLANインタフェース名を"wlan"から"eth"に修正し, ifname2に"wifi"が設定されるようにする.
ifname2に"wifi"を設定されないと, dhcpcdが起動されないように見えた.
実際のところは, はっきりいってよく分かっていない...
static void wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv)
{
    int flags;

    (省略)
    wpa_driver_wext_get_range(drv);
    drv->ifindex = if_nametoindex(drv->ifname);

    if (os_strncmp(drv->ifname, "eth", 3) == 0) {
        /*
         * Host AP driver may use both wlan# and wifi# interface in
         * wireless events. Since some of the versions included WE-18
         * support, let's add the alternative ifindex also from
         * driver_wext.c for the time being. This may be removed at
         * some point once it is believed that old versions of the
         * driver are not in use anymore.
         */
         char ifname2[IFNAMSIZ + 1];
         os_strncpy(ifname2, drv->ifname, sizeof(ifname2));
         os_memcpy(ifname2, "wifi", 4);
         wpa_driver_wext_alternative_ifindex(drv, ifname2);
     }
     wpa_driver_wext_send_oper_ifla(drv, 1, IF_OPER_DORMANT);
}

3. Wi-Fiサービス
 WifiStateTrackerのソースコードの中に, WLANインタフェース名に依存する部分があるので変更する.
ソース : ./frameworks/base/wifi/java/adnroid/net/wifi/WifiStateTracker.java
public class WifiStateTracker extends NetworkStateTracker {
     (省略)
    public void handleMessage(Message msg) {
        Intent intent;

        switch (msg.what) {
            case EVENT_SUPPLICANT_CONNECTION:
                mInterfaceName = SystemProperties.get("wlan.interface",
"eth1");
                sDnsPropNames = new String[] {
                    "dhcp." + mInterfaceName + ".dns1",
                    "dhcp." + mInterfaceName + ".dns2"
                };
                mRunState = RUN_STATE_RUNNING;
                noteRunState();
                checkUseStaticIp();
                     (省略)
         }
    }
}

今回は, ソースコードの変更箇所についてまとめてみた.
第3回では, 設定や動作の確認方法などについてまとめてみる予定.

--------
参考URL:
 [1] BC::BEATCRAFT Android_Wi-Fi

livedoor プロフィール
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

記事検索



  • ライブドアブログ