ROM コア制作記。... 予告だけ。いや、実作業の頭のあたりは忘れ去ってるし、最後のほう終わってないし。
これ書いてるのが May 23 なのにファイル名が 20030502 になってるあたりが、ハマってる程度を表している ....
... んだが、どこいじったか忘れた。
Ramdisk (/dev/mtd*1) を jffs2 とするには jffs2 イメージを作っておいて
# erase /dev/mtd1 # dd if=/root/.ram_default.jffs2 of=/dev/mtd1 bs=64k # echo dd mount -t jffs2 /dev/mtdblock1 # mount -t jffs2 /dev/mtdblock1 /mnt/ramとする。実際には pad 付きイメージを作っておいて:
# /bin/zcat /root/.ram_default.jffs2.gz > /dev/mtd1 # echo dd mount -t jffs2 /dev/mtdblock1 # mount -t jffs2 /dev/mtdblock1 /mnt/ramとして微妙に ROM をケチったが、意識してやったわけではなく script 書いた時は erase 知らなかっただけ。 cramfs は 16MB のファイルを置けない (ファイルサイズ上限は 2^24 - 1 バイト) ので、 圧縮して見た目のファイルサイズを減らしている。cramfs に入れると自動的に gzip で圧縮するようなもんなので、 事前に圧縮しても cramfs に圧縮させても量的にはあんまりかわらない .. こともなく、これくらいデカいと 数百キロバイト単位で違ってくるが、誤差っちゃー誤差だろう。
jffs2 イメージをつくるほうは:
# mkfs.jffs2 --eraseblock=0x10000 -r ramdisk_dir --pad=0x1000000 -o .ram_default.jffs2とすると ramdisk_dir/ 以下が .ram_default.jffs2 にまとめられる。 --pad=0x1000000 で 16MB まで 0xff で埋めることを指示して、 実機上で erase (jffs2 領域を 0xff で埋めて初期化する) を省略している。
カーネル 2.4.13 の時代、AC シリーズでは I/O 周りの高速化として alloc_kiovec() に変わって alloc_kiovec_sz() が導入された。 これによって blkmtd は v1.3 + sz パッチになっている。 これに対し、RMK シリーズでは blkmtd としてノーマルの v1.6 を使っている(使おうとしている)。 カーネルソースの大部分で sz 化されているにもかかわらず、blkmtd は 非 sz のままだ。
AC パッチを当てた直後に drivers/mtd/devices/blkmtd.c をバックアップして RMK パッチが当たるのを回避、sz コードで統一してから
# modprobe blkmtd device=/dev/hda # mount -t jffs2 /dev/mtdblock2 /mnt/cardなどとすることで SD を直接 JFFS2 で見ることができるが ...
"/dev/hda" そのものを jffs2 化しなければならない。
── "/dev/hda2" だけを jffs2 にするということができない。
VFAT partition をなくしてしまうわけにはいかないので断念。
うぅ、つまらんオチだ。
カーネル〜 initrd の境界は好きな位置に置けるが、カーネル、initrd を個別に ROM に書き込めるようにするには 128kB バウンダリでなければならない。 作成したカーネルはぎりぎりで 768kB を下回ったが、ふとしたきっかけで 768kB を上回った時に initrd ごと書かなければならないことになるのが煩いので、余裕をみて 896kB に。
書き換えるのは一ヶ所だけ:
*** drivers/mtd/maps/discovery-flash.c.org Mon Jun 17 10:22:57 2002
--- drivers/mtd/maps/discovery-flash.c.896 Wed Apr 30 20:00:28 2003
***************
*** 94,101 ****
static struct mtd_partition discovery_partitions[1] = {
{
name: "Filesystem",
! size: 0x00e60000,
! offset: 0x00160000
}
};
--- 94,101 ----
static struct mtd_partition discovery_partitions[1] = {
{
name: "Filesystem",
! size: 0x00e80000,
! offset: 0x00140000
}
};
むろん ROM に書き込むときは updater.pro の内容に注意する。
カーネルソースの arch/arm/mach-cotulla/discovery_deviceinfo.c で checksum の計算が行われているので、 これをそのまんまもってきて romstamp なるモノをでっちあげた。
ROM イメージを作ったあとで version number の刻印と、それに合わせて checksum を調整する。
まず ver 1.4 の ROM からカーネル、initrd 以外の領域を抽出:
# dd if=all.nb0 of=BIOS.bin bs=64k count=6 # dd if=all.nb0 of=PARAM.bin bs=64k count=2 skip=252カーネル、initrd を ROM 中に占めるサイズまで padding:
# dd if=zImage of=KERNEL.bin bs=896k conv=sync # dd if=initrd.bin of=INITRD.bin bs=14848k conv=syncもちろん、カーネル領域を 896kB 化したケースでである。1MB 取る普通のケースでは:
# dd if=zImage of=KERNEL.bin bs=1M conv=sync # dd if=initrd.bin of=INITRD.bin bs=14720k conv=syncとする。 繋げて ROM image 作成し、version を刻印する。
# cat BIOS.bin KERNEL.bin INITRD.bin PARAM.bin > ROMIMAGE # romstamp ROMIMAGE 1.41
配付目的で all.nb0 な ROM image を作成するならばともかく、 実際には不変の BIOS.bin の領域まで毎回毎回 ROM に書き込む必要はない (version 刻印は PARAM.bin の領域になされるので、checksum を直したければこれは書く必要がある) 訳だが、 書き換えしすぎで壊れる時は KERNEL.bin か INITRD.bin の領域が先なのは明らかなので気にせず ROMIMAGE 全体を書き込んでいる。
CRC 算出ループ:
unsigned int *pROMAddress = (unsigned int*)0xe8020000;
for( i = 0 ; i < uiLen ; i+=sizeof(unsigned int) ) {
crc = (((crc >> 8) & 0x00FFFFFF) ^ crc32table[(crc ^ *pROMAddress) & 0x000000FF]);
pROMAddress += 1;
}
*pROMAddress の最下位 1 バイトしか crc32table のルックアップに参加してねーよ ...。
ま、壊れる時はバーストで壊れるだろうから、これでいいんかね。
結局、マシンタイム(RTC 内で保持する時刻) を UTC とし、/etc/localtime を省略した。 /etc/adjtime が LOCAL でなく UTC になっていることを確認のこと。 TZ さえセットしておけばシステムタイム (/bin/date などが返す値) のほうは正しく日本のものをさす。
これって qtopia 1.5.0j のほうのメールの時刻が狂うってのもこの件じゃないかと思わないでもないこともないでもないが未確認。
てのはつまり、ascent/descent の解釈のことだが。Qt では font height = ascent + descent + 1 になっていて、baseline が幅をもつ。bdf では height = ascent + descent で baseline の幅はゼロ。 にもかかわらず、bdf to qpf で ascent, descent はそのまま qpf にコピーされるため、結果として font height が 1 増える。 これが LC font の本来のグリフにもかかわらず、embedded konsole で罫線の上下が繋がらない理由だ。
Underline の置き場所も、baseline 直下におかれるが、LC font では descent がゼロである結果、 Underline がフォントの外側に置かれる。 で、自前でフォントを draw しているアプリの一部で underline の消し忘れが発生する (これは embedded konsole で underline が残るバグとはあまり関係がない。こちらは別要因)。
そしてもうひとつ。枠無し embedded konsole で LC font を使うと、左端が表示外の背景黒に融けこんで読めん。
このあたり、LC font metrics と embedded konsole の metrics 処理を書き直すはめになった。
ttf のほうがフォントファイル自体は膨れるが、rotation こみにすると ttf でもっておいたほうがオトクだ。 むろん、速度的に遜色ないことは確かめておいた。 pfb などもふつーに使えたので、ttf より pfb を使うことが多いが (ファイルサイズが小さいもんで)。
... が、bdf to ttf で embedded glyph だけの日本語フォントを作る方法がないだよ。
念のためだが。lcfont10.bdf など一つの bdf を embedded glyph としただけの ttf は作れる。 ここで問題にしてるのは、lcfont10.bdf, lcfont12.bdf, lcfont16.bdf をすべて embedded glyph として含んだ ttf を作る方法がない ── という話。 一つのフォント内でサイズ違いを含んでおかないと、フォントサイズ変更にアプリが耐えられない。
で。この transformations と freetype が arm では喧嘩してくださって両立しない。なんでやねん。
余談だが。qconfig.h 中でのこれらの機能をあらわすフラグは QT_NO_TRANSFORMATIONS などと書かれているわけだが、 それらのフラグに機能を代表させて 「QT_NO_TRANSFORMATIONS と QT_NO_FREETYPE が喧嘩する」などとは表記しづらい。 TRANSFORMATIONS がないことと FREETYPE がないことが喧嘩してるわけではないからだ ... このあたり、みんな表記の仕方に苦労してるよーである。だいたい、会話するにも不便なんだがな。
ちなみに QT_TRANSFORMATIONS 入れると (← 開きなおった表現) PDF 内の rotate matrix が扱えるようになって斜体とか変形が表現できるようになるが、 座標系の扱いがバグってるらしく上下ひっくりかえるのと、mask が未実装なので色塗りがはみ出たりして笑える。
今は日本語変換ラインも使ってない(opie では使えない) ので、ボタン置く余地はあんだけど。
mount での /proc/mounts の扱いが busybox と本物の gnu mount で違う。 busybox mount を仮定する sysinfo だと本物の gnu mount 使った時に表示が変。
とくに ls が使えない ... デフォルトでは symlink を判定せず、その symlink 先が正しい先を指していないため、 ls -l するなりして symlink かどうかを目で確かめ、そのうえで手で symlink を辿らなければならない。
chroot で / を設定しなおすことができない: PATH, LIBRARY_PATH を /bin, /lib 等から外すことはできても、 /lib/ld-linux.so.2 が正しくなければならないという制約は厳しい。
同様に /lib/ld-liunux.so.2 も symlink であってはならない ... だと思ったが、 今回はいちいちテストしなかったので本当かどうかは不明。
母艦上の ${SUBSYSTEM}/rom に chroot してテスト、${SUBSYSTEM}/ をそのまま ROM 化して実機へ ── という方針がここで破綻する。