Pyon's Diary
2007-11-08 舊 平成拾玖年丁亥長月廿玖日丙午 (木・晴・立冬) [長年日記]
Vim (7.1.42) と Cscope (15.6) で C のソースを讀む。
可成り昔(七・八年前位)に觸つた事が在るだけで其乃後使ふ事も無かつたのですつかり存在自體を忘れて了つてゐた。
最近 KURO-BOX/PRO で新しいカーネルを動かす爲にカーネル・ソースを讀み始めたのだが、Vim (7.1.42) と grep だけでは辛く成つて來た。
何か良い方法は無いかと惱んでゐた處「Cscope が在つたなあ」と思ひ出したので早速入れた。
Gentoo なので
# emerge -Dav cscope
後、USE 變數に cscope を追加して Vim を再コンパイルした。
# vim /etc/make.conf # emerge -DNauv world <- 他に cscope に影響を受ける ebuild が在る事を考慮した。
處で、使ひ方を忘れて了つてゐたのと、夜中(現在午前六時半)なので頭が回つてをらず英語を讀むのも厭なので檢索して以下の頁を見附けた。
此處に書かれてゐる樣にカーネル・ソースのディレクトリに移動して、
$ cd ${WORK}/linux-2.6.22
$ make cscope CROSS_COMPILE=arm-none-eabi-
とすると cscope.* と云ふファイルが出來上がつた。此處で make に CROS_COMPILE を指定してゐるのは ARM9 用のクロス・コンパイラを利用してゐるから。
其れからペンギン飼育係が見た -- vi 系ユーザのカーネルソースコード參照環境に書いて有る樣に ${HOME}/.vimrc に以下の設定を追加した。
if has("cscope")
set csprg=/usr/bin/cscope
set csto=0
set cst
set nocsverb
" add any database in current directory
if filereadable("cscope.out")
cs add cscope.out
" else add database pointed to by environment
elseif $CSCOPE_DB != ""
cs add $CSCOPE_DB
endif
set csverb
map <C-\> :cs find s <C-R>=expand("<cword>")<CR><CR>
map <C-[> :cs find c <C-R>=expand("<cword>")<CR><CR>
endif
亦「:cscope find # <文字列>」で色々な檢索を實行出來るらしい。「#」に入るのは以下のもの。
- 0 or s -- 指定された C のシンボルを檢索する。
- 1 or g -- 指定された凾數・其乃他の定義を檢索する。
- 2 or d -- 指定された凾數に呼び出される凾數を檢索する。
- 3 or c -- 指定された凾數を呼び出してゐる凾數を檢索する。
- 4 or t -- 指定されたテキスト(文字列)を檢索する。
- 6 or e -- 指定されたパターンにマッチする文字列を egrep する。
- 7 or f -- 指定されたファイルを檢索する。
- 8 or i -- 指定されたファイルをインクルードしてゐるファイルを檢索する。
良く使ふのは map されてゐる「s」と「c」だろうな。此で讀み解きが樂に成つた。
間違つてゐたのか?。
(2007-11-19 2.6.24 カーネルのコンパイル・起動に成功した)
(2008-02-17 2.6.25-rc1 に於いて shutdown -hP で電源が落とせる樣に成つた)
數日前から KURO-BOX/PRO で 2.6.20 カーネルを動かしてみようと、
のカーネル・ソースを落としてコンパイルしてゐたのだが、實は此乃ソースでは無くて
の方を使ふべきなのでは無かろうか。
コミットの日付を日付を見て其乃樣に感じたので、
以降の投稿を流して行つた(讀んだ譯では無くて「kernel_universal」で頁内檢索をしただけ)ら以下の投稿を見附けた。
先の投稿ではリポジトリの場處が
https://linkstationwiki.svn.sourceforge.net/svnroot/linkstationwiki/kernel_arm9/trunk/src/linux-2.6.22/
だつたのにいつの間にか、
https://linkstationwiki.svn.sourceforge.net/svnroot/linkstationwiki/kernel_universal/linux-2.6.22/
に成つてゐた。
英語がきちんと讀め無いと斯う云ふ時辛いなあ。
追記: 2.6.23 (2007-11-08)
以下の投稿に據ると現在は 2.6.23 が最新らしい。
此に據ると、
- リポジトリは https://linkstationwiki.svn.sourceforge.net/svnroot/linkstationwiki/kernel_universal/linux-2.6.23/
- XOR サポートは動かない。(試驗しない場合は .config で無効にする事)
- NAND (JFFS2) パーティションはマウント出來る樣に成つた。(マウントし度い場合は .config で有効にする事)
- 但し NAND パーティションからブートは出來無い。
との事。
KURO-BOX/PRO (No.30) ARM9 用 2.6.23 カーネルのコンパイルで嵌つた。(コンパイラを ARM 2006q3-27 に換へたら上手く行つた)
(2007-11-19 2.6.24 カーネルのコンパイル・起動に成功した)
(2008-02-17 2.6.25-rc1 に於いて shutdown -hP で電源が落とせる樣に成つた)
ARM9 用 2.6.23 カーネル をリポジトリから落として來て普通に、
% cd ${WORK}/linux-2.6.23
% cp config/config_kuroboxpro .config
% make oldconfig
% make menuconfig
% make uImage
として arch/arm/boot の下でイメージファイルを確認して見ると、
% cd arch/arm/boot % ls -l uImage zImage -rw-r--r-- 1 #### ##### 5008820 2007-11-08 10:32 uImage -rwxr-xr-x 1 #### ##### 5008756 2007-11-08 10:32 zImage
5MB と云ふのはどういふ事だ?。
vmlinux も粗同樣のファイルサイズだつたので壓縮されてゐない模樣。
良く判ら無いので取敢へず手で壓縮した。
% cd ${WORK}/linux-2.6.23/arch/arm/boot
% gzip zImage
% mv zImage.gz zImage
% cd ../../../
% make uImage
(中略)
Kernel: arch/arm/boot/zImage is ready
UIMAGE arch/arm/boot/uImage
Image Name: Linux-2.6.23-20071108
Created: Fri Nov 9 00:06:46 2007
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1877153 Bytes = 1833.16 kB = 1.79 MB
Load Address: 0x00008000
Entry Point: 0x00008000
Image arch/arm/boot/uImage is ready
% ls -l arch/arm/boot/[uz]Image
-rw-r--r-- 1 #### ##### 1877217 2007-11-09 00:06 arch/arm/boot/uImage
-rwxr-xr-x 1 #### ##### 1877153 2007-11-09 00:06 arch/arm/boot/zImage
此を KURO-BOX/PRO に持つて行つて起動したらパニクつた。
追記: クロス・コンパイラを GNU Toolchain for ARM 2006q3-27 に換へたら上手く行つた。(2007-11-09)
他に思ひ當たる事も無いのでコンパイラが駄目なのかと思ひ、コンパイラを
から
に換へたら zImage と uImage のファイル・サイズが普通に成つた。
% cd ${WORK}/linux-2.6.23
% ls -l vmlinux arch/arm/boot/[uz]Image
-rw-r--r-- 1 pyon users 1911956 2007-11-09 16:34 arch/arm/boot/uImage
-rwxr-xr-x 1 pyon users 1911892 2007-11-09 16:08 arch/arm/boot/zImage
-rwxr-xr-x 1 pyon users 5059849 2007-11-09 16:08 vmlinux
斯う云ふのつて本當良く判ら無い。
でも此を KURO-BOX/PRO に持つて行つたら起動した。良かつた。
が然し、亦 MAC アドレスが筐體の其處に記載されてゐるのと違つてゐた。
追記: MAC アドレスを H/W から取得する樣に修正した。(2007-11-09)
先づは先日の經驗を基に凾數 mvEthMacAddrGet() を使用してゐる箇所を探すと三箇所在つた。
Cscope タグ: mvEthMacAddrGet
# 行番号 ファイル名 / 文脈 / 行
1 505 arch/arm/mach-mv88fxx81/LSP/egiga/mv_e_main.c <<egiga_load>>
mvEthMacAddrGet(port, dev->dev_addr);
2 599 arch/arm/mach-mv88fxx81/LSP/mv_gateway/mv_gtw_main.c <<init_config>>
mvEthMacAddrGet(EGIGA_DEF_PORT, tmp_addr);
3 2265 drivers/net/egiga/mv_ethernet_main.c <<eth_mac_addr_get>>
mvEthMacAddrGet(port, addr);
勘で三番目の凾數にデバッグ・コードを入れて見た所、起動メッセージに其乃出力が出たので其處を通過してゐる事が判つた。其れで凾數 eth_mac_addr_get() (drivers/net/egiga/mv_ethernet_main.c, 2265) を眺めて見ると以下の樣に成つてゐた。
0172 extern unsigned char mvMacAddr [6];
(中略)
2258 for (i=0 ; i<6 ; i++)
2259 {
2260 if (mvMacAddr[i] != 0) break;
2261 }
2262 /* if mvMacAddr is Zero then read from the Port itself */
2263 if (i==6)
2264 {
2265 mvEthMacAddrGet(port, addr);
2266 }
廣域變數 mvMacAddr の要素全てが 0x00 の時凾數 mvEthMacAddrGet() が呼び出されてハードウェアから MAC アドレスが讀出される事が判つた。其處で廣域變數 mvMacAddr の値を出力する樣にして確認すると既に變な値が入つてゐた。
其處で廣域變數 mvMacAddr に値を代入してゐる所を探した。
Cscope タグ: mvMacAddr
# 行番号 ファイル名 / 文脈 / 行
4 159 arch/arm/mach-mv88fxx81/LSP/core.c <<parse_tag_mv_uboot>>
memcpy(mvMacAddr, tag->u.mv_uboot.macAddr, 6);
5 924 arch/arm/mach-mv88fxx81/LSP/core.c <<mv_fixup>>
memcpy(mvMacAddr, mv_uboot->macAddr, 6);
6 927 arch/arm/mach-mv88fxx81/LSP/core.c <<mv_fixup>>
memcpy(mvMacAddr, mv_uboot->macAddr, 6);
變數を宣言してゐる箇所、値を參照してゐる所は省いた。此れ等の前後で値を出力して何處で出鱈目が値が設定されてゐるかを確認した處、凾數 mv_fixup() (arch/arm/mach-mv88fxx81/LSP/core.c, 927)で出鱈目な値が設定されてゐた。
實際ソース・コードを眺めると、
921 if( mvUbootVer > 0x01040100 ) // releases after 1.4.2
922 overEthAddr = mv_uboot->overEthAddr;
923 else if (mvUbootVer >= 0x01090200) {
924 memcpy(mvMacAddr, mv_uboot->macAddr, 6);
925 }
926
927 memcpy(mvMacAddr, mv_uboot->macAddr, 6);
928 break;
と成つてゐて 924 と 927 で處理が重複してゐて 921 〜 925 の處理が意味無しに成つてゐた。此は削除して代はりに以下の樣にすべきでは無かろうか。
廣域變數 mvMacAddr は arch/arm/mach-mv88fxx81/LSP/core.c の 98 行目で以下の樣に初期化されてゐる。
98 u8 mvMacAddr[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
然し上に書いた樣に凾數 eth_mac_addr_get() (drivers/net/egiga/mv_ethernet_main.c, 2265) では、mvMacAddr の全ての要素が 0x00 だつた場合に tag (?) から取得してゐるので初期條件と其乃後の比較が噛み合つてゐ無い。だから以下の樣に修正した。
先づ arch/arm/mach-mv88fxx81/LSP/core.c から
@@ -924,7 +924,6 @@ memcpy(mvMacAddr, mv_uboot->macAddr, 6); } - memcpy(mvMacAddr, mv_uboot->macAddr, 6); break; }
次に drivers/net/egiga/mv_ethernet_main.c を
@@ -2257,7 +2257,7 @@
int i;
for (i=0 ; i<6 ; i++)
{
- if (mvMacAddr[i] != 0) break;
+ if (mvMacAddr[i] != 0xFF) break;
}
/* if mvMacAddr is Zero then read from the Port itself */
if (i==6)
此でコンパイルして出來上がつたカーネル・イメージ及びモジュール・ファイルを KURO-BOX/PRO に持つて行き再起動した處、TAG から MAC アドレスを取得する樣に成つた。
亦フォーラムに書かれてゐた樣に NAND (JFFS2) がマウント出來るか爲して見たらマウント出來た。但し壞すのは厭だつたので書込みはし無かつた。