[解決済み]AR7240のkld問題

2018/01/02にEDさんが修正してくれました。

https://svnweb.freebsd.org/base?view=revision&revision=327489

AR7240なルーターをFreeBSD-Currentにして使っていて、久しぶりにアップデートをしたところ、以下のエラーメッセージが表示されて、kldが使えなくなった。

```
kldload: an error occurred while loading the module. Please check dmesg(8) for more details.
```

ZRouterではmdをkldで使っているので/tmpが使えなくなり正常に使えない状態になってしまいました。T T

よくとくブートログを見るとこんなログがあった。

```
link_elf_lookup_symbol: missing symbol hash table
```

kldは依存関係のバージョンをチェックするのだが大元のkernelのバージョンが読めてないので、kldが読めなくなっているようだ。

で何が悪いかsys/kernのコードを見たりreadelfコマンドでELF kernelファイルを見てみたがよく分からなかったので、とりあえず生のELF kernelをU-Bootで起動してみた。

```
ar7240> setenv ipaddr 10.10.10.99
ar7240> setenv serverip 10.10.10.3
ar7240> tftpboot 80050000 Buffalo_WHR-HP-G300N_kernel
ar7240> bootelf
```

これでは正常に起動してkldも使える。次はこのELFから生成したu-bootのイメージをブートしてみる。

```
ar7240> setenv ipaddr 10.10.10.99
ar7240> setenv serverip 10.10.10.3
ar7240> tftpboot 0x80800000 Buffalo_WHR-HP-G300N_kernel.kbin.oldlzma.uboot
ar7240> bootm
```

やはりこれだと上記のログがでてkldが使えない。

でいろいろ調べてみても分からず、とりあえず3/15のheadのソースをsvnからcoして試してみたがダメだった。

あきらめずに2/1のソースをcoして試したところ問題が起きなくなった。

そもそもELFからimageは以下のようなツールにより処理をしている。

objcopy -> oldlzma -> uboot_mkimage

このタイミングでcontrib/binutilのobjcopyからcontrib/elftoolchainのobjcopy(elfcopy)に切り替えられたようです。

objcopyは前はGNU objcopy 2.17.50 [FreeBSD] 2007-07-03でしたが現在はelftoolchain r3400Mになっています。

これが原因で、古いobjcopyを使えば問題が起きなくなりました。

不思議な事にRT3050とかAR2315では問題が起きません。と書いて気がついたが、AR2315はRedBootでobjcopyしていなようです。エンディアンに関係した問題の可能性があるかもしれません。

2016/6/7現在objcopy (elftoolchain r3477M)になっていますが、問題は解消していません。

2017/6/16現在もまだ問題解消していません。古いobjcopyで作ったものと、新しいobjcopyで作ったものを確認したところ、やはりエンディアンが逆になっているようです。。。11Rはまだ古いままでCURRENTだからしかたがないといえとっても困ったものです。

elftoolchainに切り替えて古いbinutilsが使えるようにWITHOUT_ELFCOPY_AS_OBJCOPYというビルド設定が当初はあったようですが、すでに[無くなって](https://reviews.freebsd.org/D7337)います。このメモを書いたのが2016/5でMLにも問題あるってポストしたと思うのだが、2016/10に外されています。Tier3の事なんか、眼中に無いのかもしれません。

なぜelfでなくkbin(binary)を使っているかというと、新しめのU-Bootはelfのサポートがありますが、古いものはないので一律kbinにしています。

```
microserver % cmp -l Onion_Omega_kernel.binutil.ok Onion_Omega_kernel.elfcopy.ng
 | head
3055349   0   3
3055350   0  20
3055351  20   0
3055352   3   0
3055353   0 111
3055354   0  32
3055355  32   0
3055356 111   0
3055357   0  21
3055358   0  24
```

readelfで見てみるとこんな感じ。

```
microserver % readelf -S Onion_Omega_kernel
There are 30 section headers, starting at offset 0x464c60:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        80050120 000120 2b0c90 00  AX  0   0 16
  [ 2] .MIPS.stubs       PROGBITS        80300db0 2b0db0 000010 00  AX  0   0  4
  [ 3] .rodata           PROGBITS        80300dc0 2b0dc0 03c820 00   A  0   0 16
  [ 4] set_sysctl_set    PROGBITS        8033d5e0 2ed5e0 0010d4 00   A  0   0  4
  [ 5] set_sysuninit_set PROGBITS        8033e6b4 2ee6b4 0004ac 00   A  0   0  4
  [ 6] set_sysinit_set   PROGBITS        8033eb60 2eeb60 0008ec 00   A  0   0  4
  [ 7] set_cam_xpt_xport PROGBITS        8033f44c 2ef44c 000028 00   A  0   0  4
  [ 8] set_modmetadata_s PROGBITS        8033f474 2ef474 000464 00   A  0   0  4
  [ 9] set_cam_xpt_proto PROGBITS        8033f8d8 2ef8d8 000010 00   A  0   0  4
  [10] set_kdb_dbbe_set  PROGBITS        8033f8e8 2ef8e8 000008 00   A  0   0  4
  [11] set_cons_set      PROGBITS        8033f8f0 2ef8f0 000008 00   A  0   0  4
  [12] usb_host_id       PROGBITS        8033f900 2ef900 000040 00   A  0   0 32
  [13] set_kbddriver_set PROGBITS        8033f940 2ef940 000004 00   A  0   0  4
  [14] .interp           PROGBITS        8033f944 2ef944 00000d 00   A  0   0  1
  [15] .hash             HASH            8033f954 2ef954 00a9a8 04   A 16   0  4
  [16] .dynsym           DYNSYM          8034a2fc 2fa2fc 01a650 10   A 17   1  4
  [17] .dynstr           STRTAB          8036494c 31494c 01a1f5 00   A  0   0  1
  [18] .reginfo          MIPS_REGINFO    8037eb44 32eb44 000018 18   A  0   0  4
  [19] .data             PROGBITS        80382000 332000 039700 00  WA  0   0 8192
  [20] .rld_map          PROGBITS        803bb700 36b700 000004 00  WA  0   0  4
  [21] set_pcpu          PROGBITS        803bb740 36b740 000d04 00  WA  0   0 64
  [22] .got              PROGBITS        803bc450 36c450 001668 04 WAp  0   0 16
  [23] .dynamic          DYNAMIC         803bdab8 36dab8 0000c8 08   A 17   0  4
  [24] .bss              NOBITS          803bdb80 36db80 028e10 00  WA  0   0 64
  [25] .comment          PROGBITS        00000000 36db80 007b58 00      0   0  1
  [26] .pdr              PROGBITS        00000000 3756d8 048ec0 00      0   0  4
  [27] .shstrtab         STRTAB          00000000 3be598 000142 00      0   0  1
  [28] .symtab           SYMTAB          00000000 3be6dc 046400 10     29 11229  4
  [29] .strtab           STRTAB          00000000 404adc 060184 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

```

15,16,23のブロックのコピーがおかしくなってるみたい。

elfcopyはlibelfのelf_getdata()を使っていて、この中で変換しているのだが、それがm4で書かれてしまっていて、どう動いているのかよくわからない。