トップ «前の日記(2003年03月26日) 最新 次の日記(2003年03月28日)» 編集
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|10|12|
2009|02|03|06|07|10|11|12|
2010|01|02|03|04|07|09|10|11|12|
2011|01|03|04|05|06|07|08|10|
2012|01|06|08|09|10|12|
2013|01|02|03|04|07|09|11|12|
2014|01|03|04|05|06|09|
2015|04|
2016|01|08|
ここは旧えびめもです。えびめも2に移行します(2016/12/1)

2003年03月27日

CAT709

shに限らずi386でも同じと思うが、linux-2.4.19カーネルで、"jffs2"と"PPP Deflate compression"を両方ともYにするとコンパイルエラーが出てしまった。

drivers/net/net.o: In function `deflate':
/home/ebihara/project/sh/cat709/linux-2.4.19-cat709/drivers/net/zlib.c:974: multiple definition of `deflate'
fs/fs.o:/home/ebihara/project/sh/cat709/linux-2.4.19-cat709/fs/jffs2/zlib.c:974: first defined here
drivers/net/net.o: In function `_tr_flush_block':
/home/ebihara/project/sh/cat709/linux-2.4.19-cat709/drivers/net/zlib.c:2687: multiple definition of `_tr_flush_block'
fs/fs.o:/home/ebihara/project/sh/cat709/linux-2.4.19-cat709/fs/jffs2/zlib.c:2687: first defined here
drivers/net/net.o: In function `zlibVersion':
/home/ebihara/project/sh/cat709/linux-2.4.19-cat709/drivers/net/zlib.c:5145: multiple definition of `zlibVersion'
略
エラーメッセージから判断すると、jffs2もPPP Deflate compressionも両方ともzlib圧縮ルーチンを使うのだが、どちらもzlibを静的リンクしようとするので2重定義エラーが出てしまうようだ(こりゃカーネルのbugだな)。具体的に言うと drivers/net/zlib.c と fs/jffs2/zlib.c の両方をリンクしようとするのでエラーが出ている。 こちらに同様の報告を見つけた
さて、ぼちぼちと kenerl-hack 開始だ。まず、両方のzlib.cの差分を見てみる
$ diff -u drivers/net/zlib.c fs/jffs2/zlib.c
--- drivers/net/zlib.c  Sat Aug  3 09:39:44 2002
+++ fs/jffs2/zlib.c     Sat Aug  3 09:39:45 2002
@@ -433,7 +433,7 @@
     int nice_match; /* Stop searching when current match exceeds this */
                 /* used by trees.c: */
-    /* Didn't use ct_data typedef below to suppress compiler warning */
+    /* Didn't use ct_data typedef below to supress compiler warning */
     struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
     struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
     struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
@@ -689,7 +689,7 @@
 /* ===========================================================================
  * Update a hash value with the given input byte
- * IN  assertion: all calls to UPDATE_HASH are made with consecutive
+ * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
  *    input characters, so that a running hash key can be computed from the
  *    previous key instead of complete recalculation each time.
  */
@@ -700,7 +700,7 @@
  * Insert string str in the dictionary and set match_head to the previous head
  * of the hash chain (the most recent string with same hash key). Return
  * the previous length of the hash chain.
- * IN  assertion: all calls to INSERT_STRING are made with consecutive
+ * IN  assertion: all calls to to INSERT_STRING are made with consecutive
  *    input characters and the first MIN_MATCH bytes of str are valid
  *    (except for the last MIN_MATCH-1 bytes of the input file).
  */
@@ -2065,7 +2065,7 @@
  */
 local void tr_static_init()
 {
-    static int static_init_done;
+    static int static_init_done = 0;
     int n;        /* iterates over tree elements */
     int bits;     /* bit counter */
     int length;   /* length value */
コメントのスペルミス(笑)以外違いはまったくないし、static変数を=0で初期化している部分だけ違うが、linuxではstatic変数は0初期化されることが保障されているので実質的にはどちらもまったく同じコードだということがわかった。とりあえず jffs2は/のマウントに必要だから必ずYで組み込むことケテーイなので drivers/net/zlib.c を捨てる作戦に出る。

drivers/net/Makefile を見てもzlib.oのリンクの記述が見つからない。あれれ?おかしいなと、grepしたところ drivers/net/ppp_deflate.c に

#include "zlib.c"
を発見。ぬわんだこれは?? .c ソースをincludeしてやがる。これを直すのは面倒そうなので、fs/jffs2/Makefileを修正して
 COMPR_OBJS     := compr.o compr_rubin.o compr_rtime.o pushpull.o \
-                      compr_zlib.o zlib.o
+                      compr_zlib.o
とpatchした。これでコンパイルが通ったし起動もOKだったので、応急処置はできたとおもうが、これで対処できるのは「jffs2とPPP Deflate compressionを両方ともYにしたときのリンクエラー」の対応のみだ。jffs2のzlibのリンクを削っているので当然PPP Deflate compressionをYにしなければjffs2に必要なzlibが組み込まれない。こんな対応をせずともPPP側をモジュールにすればリンクエラーは出ないので、すなおにモジュールにしたほうがよさそうだ(jffs2は/のマウントに必要なのでモジュールにできない)

jffs2とppp圧縮が両方ともzlibのインスタンスを組み込もうとしているので実はzlibはスレッドセーフじゃないのかもしれないという一抹の不安は残る。