2010年6月24日木曜日

埋め込みストレージにswap

ECOのswap実装をみて、、、
ちゅーと半端な実装なら、いっそ外部ツールに任せてswapは実装しない方向でいいと思うけど。
と、思った。(´・ω・`)

それはさておき。
まずは前口上から。

以下、基本的な知識があるという前提で書く。
ハッキリ言って、Linuxコマンドラインや、Androidのadbシェルが理解できない人、下記手順が何をしているのか分からない人はやらないほうがいい。


と、とりあえず警告だけはしとく
(・∀・)


さて、前回までにおおかたの準備ができた。
無理やり埋め込んだUSBメモリは元気に動いてるっぽい。
で、今回はそこに swap領域を作って動かすのと、残りをUSBストレージとして利用するための準備をする。

ベースはECOTOX ROM ver1.0
オリジナルファーム 1.7.2でも同じだと思う。
やってることは大したことではないので、他のROMでも手を入れれば動くはず。

まずはadbシェルを使ってM001内での作業。
DOS窓からログインしてsu。adb shellする方法なんかはググって頂戴。
adb shell

$ su
さて、埋め込んだUSBメモリが/dev/block/sda として認識されたとする(コレを知る方法はdmesgを読むべし)

まずはデバイスの初期化。
fdiskでパーティションを切りなおす。
# fdisk /dev/block/sda
fdiskでの作業は、
既存のパーティションを削除。
第1パーティションをLinux swap領域として確保(例えば256M)
残り全部、第2パーティションをFAT32-LBAとして確保。
パーティションテーブルを書き込んでおしまい。

こんな感じ。
Disk /dev/block/sda: 3959 MB, 3959422976 bytes
126 heads, 61 sectors/track, 1006 cylinders
Units = cylinders of 7686 * 512 = 3935232 bytes

         Device Boot      Start         End      Blocks  Id System
/dev/block/sda1               1          66      253607+ 82 Linux swap
/dev/block/sda2              67        1000     3589362   c Win95 FAT32 (LBA)
次にswap領域のフォーマット
# mkswap /dev/block/sda1
これで、swap領域が確保された。
で、残りの領域をvfatでフォーマットしたいところなんだけど、ファームに付いてる mkfs.vfat では2G以上の領域をフォーマットできないっぽい。
エラーになってダメ。
仕方ないのでフォーマットは後回しにする。

もし、swapだけできればいいと言う場合はこれで作業はおしまい。
後はSwapper系ツールで、/dev/block/sda1 をスワップパーティションとして指定してやればいい。

でも、それでは面白くないので、
swapon他の処理をブートシーケンスに完全に組み込んでしまうことにする。

処理を行うスクリプトは下記のような内容。
ファイル名を etcinit.sh とする。
#!/system/bin/sh

# swapon to sda1
count=10
until [ $count -eq 0 ];
do
  if [ -b /dev/block/sda1 ] ; then
    swapon /dev/block/sda1
    echo 30 > /proc/sys/vm/swappiness
    sysctl -w vm.swappiness=30

    break
  fi

  sleep 3
  count=`expr $count - 1`
done

# mount sda2
if [ -b /dev/block/sda2 ] ; then
  mkdir /ExtDisk
  /system/bin/mount -o dirsync,nosuid,nodev,noexec,utf8,uid=1000,gid=1015,fmask=702,dmask=702,shortname=mixed -t vfat dev/block/sda2 /ExtDisk
fi
やってることは、swaponとdev/block/sda2 を /ExtDisk ディレクトリに mount している。
何度かテストした結果、init.rcの実行よりsdaの認識が微妙に遅れる場合があるので、ループとsleepで時間稼ぎをしながらsdaの存在をチェックしている。
ちなみに、スクリプトファイルをWindowsで作る時、改行コードに注意して保存すること。

お次はスクリプトの転送。
まず、adbシェルを抜けて、etcinit.sh を、/ に adb pushする。
ファイルパスは適当に読みかえるべし。
adb push e:\etcinit.sh /
で、再び、adb shellでの作業。
adb shell

$ su
# chown 0:0 etcinit.sh
# chmod +x etcinit.sh

最後の仕上げ。
init.rcの改造。

init.rcをエディタで開いて、スクリプトの最後の方、usbgadget.shを呼び出す手前に、次の2行を入れる。
#service usrinit /usrinit.sh
#    oneshot
service etcinit /etcinit.sh
    oneshot
service usbgadget /usbgadget.sh
    oneshot

ついでに、ECOのスクリプトはコメントアウト。
init.rcを保存して完了。

上記の改造を施した init.rcをWindowsで作っておいて、adb pushしてadb shellからchown & chmodする方法でもおk。
私は面倒だったから、M001上のConnectBotで直接viで編集したけど。


さて、再起動!!
うぃんうぃんうぃん・・・(・∀・)きたー!
# free
              total         used         free       shared      buffers
  Mem:       101472        99620         1852            0            4
 Swap:       253596         4804       248792
Total:       355068       104424       250644


# cat /proc/swaps
Filename                             Type            Size    Used    Priority
/dev/block/sda1                      partition       253596  4872    -1

# df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/root               150528     71696     78832  48% /
tmpfs                    50736        16     50720   0% /dev
tmpfs                     4096         0      4096   0% /sqlite_stmt_journals
/dev/block/mtdblock8    153600     45144    108456  29% /data
/dev/block/mtdblock9    102400      4616     97784   5% /cache
/dev/block/mtdblock11  1678336     14488   1663848   1% /UserSpace
/dev/block/sda2        3581168         0   3581168   0% /ExtDisk
/dev/block/loop0       1507540      4828   1502712   0% /LocalDisk
/dev/block//vold/179:1 3858432    823520   3034912  21% /sdcard


以上、

/dev/block/sda1 は swap
/dev/block/sda2 は /ExtDisk に mountされている。

これで、電源オンで内蔵ストレージにサクッとswapon♪
SDカード抜き差しの心配もいらない(´∀`)

うむ、ずばり自己満足だけだなw

で、
ひとまず、長くなったのでおしまい。

埋め込みメモリの残り物をUSBストレージとして認識するのはまた次回。

0 件のコメント:

コメントを投稿