2018/01/02にEDさんが修正してくれました。
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というビルド設定が当初はあったようですが、すでに無くなっています。このメモを書いたのが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で書かれてしまっていて、どう動いているのかよくわからない。