RT1310A

写真(2016-05-21 22.20) #2
お約束ですが、このページのいかなる記載においても著者は一切の責任をおいません。

MIPSなルータをいろいろハードオフで買ってきていじって いるが、ARMなルーターもたまにあって、手元のRT1310Aなルーターがあるので 、ちょっといじってみようかと思う。

ターゲットはバッファローのWZR2-G300NでブートはU-BootでFlash 4M/SDRAM 16Mで ある。CPUはARM926EJSでVersion5TE(ARM9Eファミリ)のようだ。 FreeBSDのソースツリーにはこのSOCのコードは無いがARM926EJSなコードを 参考に作ってみようかと思う。ハードの情報はデーターシートは入手できていないが GPLな公開されているコードや、既存のLinuxのログなどを参考にする。 いまのことろ他のBSD関係で試している人は見当たらない。

チップにもプリントしてあるがこのチップは5V Technologiesの5VT1310のOEMだと思う。 Ralinkは11nなチップセットをかなり早い時期に投入していて、無線のチップセット だけではビジネス的に難しいため、ARM SOCをOEMして提供したのではないかと考え られる。その後おそらく、買収などでMIPS SOCを作れるようになったので、 このチップ以降はMIPS SOCを提供するようになったのでは想像される。 5V Technologiesは製品があまり多くなく小規模な会社と思われる。 5VT1310は2005年くらいからあったようで、5VT9000_MPW1というコード名も使われて いたようだ。5VT1310を使った製品は以下のような物があったようだ。

BUFFALOWZR2-G300N
PCIMZK-W04N
EdimaxBR-6504N
BELKINF5D8231-4 v3
AIRLINKAR680W
NetCommNP740n
D-LinkWBR-1310
PheeNet TechnologyWLn-501
SandbbergWireless N300 Router
LG
Seednet
Yahoo! BB
NTT DoCoMoケータイホームシステム(宅内制御装置・家電制御アダプタ)

UrJTAGで見てみたら以下のような情報が確認できたが、定義ファイルが無いので JTAGを使うのは難しいと思われる。

jtag> detect
IR length: 4
Chain length: 1
Device Id: 00000111100100100110111100001111 (0x0000000007926F0F)
  Manufacturer: ARM
Cannot open /Users/hiroki/Develop/Device/OpenSrouce/urjtag-0.10/urjtag/arm/PARTS
  Unknown part!
chain.c(149) Part 0 without active instruction
chain.c(200) Part 0 without active instruction
chain.c(149) Part 0 without active instruction

実は新品を買って自宅で長らく使っている PlanexのMZK-W04Nも同じチップを使っていた。 あまり調子が良くないので、交換したいと思っているが。。。

WZR2-G300NのEther SwitchはIP175Cを使って いて、このコードはsys/dev/etherswitchにあります。MACが使えるようになればですが。

現在のsys/armの下のコードでARM926EJSがターゲーットになっている、lpc(NXP)と mv(Marvell)なのだがmvは作り込みが強く、作り込んでいないlpcを参考にすること にした。at91(Atmel)もARM9なコードのようだが、いろいろなチップに対応する コードになっていて複雑で参考にするには厳しい。


FreeBSDのarm関係のカーネルソース

FreeBSD/armはARM922(ARM9ファミリ Version4)なarm/cavium/cns11xxが最低サポート ラインで、その上にARM926EJ-S(ARM9Eファミリ Version5TE) がある。lpc,mv,at91が このタイプになっている。この二つはarm/locore-v4.Sが起動時に最初に呼ばれて、 それ以外はlocore-v6.Sが呼ばれるようだ。これら以外はarm11かCortex Aとなる。 armはいろいろなバージョンがある上に呼び名がいろいろあって、たいへん分かりにくい。

ビルドはZRouterでおこなっていて、ZRouterに元々入っていたixpなターゲットを 参考にファイルを用意してみた。ixpはビックエンディアンだったんですが、 ゴーストがささやいてそうではない気がして、armebからarmに変更しました。 当たっていたのですが、簡単に確かめる方法ありますかね。。。ソースコードの方は ビルドの環境になるし、入っているLinuxでオペレーションできたとしてもコマンドが 限られていて良い方法が思いつきません。

コンパイルしていてfdt関係でエラーがでて、調べてみたら Flattened Device Tree という仕組みでhintsの代わりの仕組みになるようだ。sys/armの方にはかなり 取り入れているが、sys/mipsの方にはあまり取り入れられてないようだ。 カーネルビルド時にはsrc/sys/boot/fdt/dts/にあるファイルがdtcというツールで コンパイルされて、カーネルに入れられるようだ。

FDTはブートから渡されるデータを元にカーネルのデバイスコンフィグレーションを おこなう仕組みで、対応していないブートの場合はカーネル内にdtsをコンパイルした dtbファイルを入れてこれを元にコンフィグレーションをおこなうようだ。 元々OpenFirmware/Powerから出てきた仕様のようだ。昔MacがPowerPCだったころPCIな デバイスドライバを作っていて似たような仕様があったような記憶があるがもう10年 以上前の話で思い出せない。

まずはリブートデバッグで、U-Bootからちゃんと自分のコードに実行が移っているかを 確認してUARTがちゃんと使えるようになるようになれば良いのだが。

Marvellのポーティングは ここに資 料があった。FDTが入る前なので、少し現在とは変わってしまっているところもあるが。

ZRouterでビルドしたカーネルの逆アセンブラは以下のようにして出来る。

`find tmp/arm.arm -name objdump -type f | head -1` -d Buffalo_WZR2-G300N_kernel

ZRouterでビルドして先頭にリセットするコードを入れて確認していたところ、 案外簡単に起動までは確認できたが、MMUの設定でかなり手こずった。 NetBSDの起動処理を解説している rpi_start.Sを読む (第1回) などを参考にして理解してみた。

Buffalo_WZR2-G300N_kernel:     file format elf32-littlearm

Disassembly of section .text:

c0000100 <_start>:
c0000100:       e1a09000        mov     r9, r0
c0000104:       e1a08001        mov     r8, r1
c0000108:       e1a0c002        mov     ip, r2
c000010c:       e1a0b003        mov     fp, r3
c0000110:       e10f7000        mrs     r7, CPSR
c0000114:       e38770c0        orr     r7, r7, #192    ; 0xc0
c0000118:       e121f007        msr     CPSR_c, r7

c000011c <disable_mmu>:
c000011c:       ee112f10        mrc     15, 0, r2, cr1, cr0, {0}
c0000120:       e3c2200d        bic     r2, r2, #13     ; 0xd
c0000124:       e3c22a01        bic     r2, r2, #4096   ; 0x1000
c0000128:       e3c22b02        bic     r2, r2, #2048   ; 0x800
c000012c:       ee012f10        mcr     15, 0, r2, cr1, cr0, {0}
c0000130:       e1a00000        nop                     (mov r0,r0)
c0000134:       e1a00000        nop                     (mov r0,r0)
c0000138:       e1a00000        nop                     (mov r0,r0)
c000013c:       ee120f10        mrc     15, 0, r0, cr2, cr0, {0}
c0000140:       e1a00000        nop                     (mov r0,r0)
c0000144:       e24ff004        sub     pc, pc, #4      ; 0x4

c0000148 <Lunmapped>:
c0000148:       e28f0f41        add     r0, pc, #260    ; 0x104
c000014c:       eb000031        bl      c0000218 <translate_va_to_pa>
c0000150:       e3a05101        mov     r5, #1073741824 ; 0x40000000

当初sys/mipsと同じように物理アドレスでビルドしていたが、よくよくアセンブラ と逆アセンブラを読んでみたところ、ここら辺の値を使って仮想アドレスに移っていて 0xc000 0000でビルドしないとダメな事に気がついた。ただしU-Bootのヘッダーの方には 物理アドレスを指定している。


c0000254 <Lpagetable>:
c0000254:       c0000254        .word   0xc0000254
c0000258:       c0348000        .word   0xc0348000

c000025c <Lreal_start>:
c000025c:       c0000100        .word   0xc0000100

c0000260 <Lend>:
c0000260:       c031bc24        .word   0xc031bc24
c0000264:       c031bc24        .word   0xc031bc24
c0000268:       c0345afc        .word   0xc0345afc
c000026c:       c031e000        .word   0xc031e000

メモリの遷移
% file Buffalo_WZR2-G300N_kernel
Buffalo_WZR2-G300N_kernel: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dyn
amically linked (uses shared libs), for FreeBSD 11.0 (1100080), not stripped
% file Buffalo_WZR2-G300N_kernel.kbin.oldlzma.uboot
Buffalo_WZR2-G300N_kernel.kbin.oldlzma.uboot: u-boot legacy uImage, FreeBSD Kern
el Image, Linux/ARM, OS Kernel Image (lzma), 1137320 bytes, Thu Nov 19 20:01:56 
2015, Load Address: 0x40000100, Entry Point: 0x40000100, Header CRC: 0x8562228F,
 Data CRC: 0x56FF7484
% readelf -h Buffalo_WZR2-G300N_kernel
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0xc0000100
  Start of program headers:          52 (bytes into file)
  Start of section headers:          3317864 (bytes into file)
  Flags:                             0x4000002, has entry point, Version4 EABI
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         5
  Size of section headers:           40 (bytes)
  Number of section headers:         29
  Section header string table index: 26

結局いろいろ試したがMMU設定後にはリセットのコードが動かなくなるようで、UART を使った確認に変更した。昔の会社の先輩直伝のmorimoridebugという関数で確認して みた。:)

I/Oのマップはarm_devmap_add_entry()でアドレスを登録して (最大32:AKVA_DEVMAP_MAX_ENTRIES)、arm_devmap_bootstrap() するとKVMの領域にマップされる。lpc_machdep.cを見ると、I/O空間の物理アドレスを arm_devmap_add_entryで渡して、元々の物理アドレスでbus_space_mapに 渡してbus_space_write_4でアクセスするようだ。

arm_devmap_add_entryは小さいアドレスから順に登録しないといきなり落ちます。

ほとんどのコードでarm_devmap_add_entryの設定値は直値になっているがfdtから 拾うべきなんだと思う。コンソールが使えるまでの処理は出来るだけ複雑にすべきでは ないと思うのですが、既にメモリサイズとUARTをFDTに依存しているので、バスの アドレスも入れてもいいとおもう。これによりソースファイルは修正しなくても dtsファイルの修正のみで同じタイプのSOCの起動は確認できるようになる。

コンソールが使えるようになる前のEARLY_PRINTFというデバッグ方法もあって、 sys/armではSOCDEV_VA,SOCDEV_PAでUARTをmapしておいてそのアドレスに直接データ を書き込んで確認できるようにするようだ。at91とかにはそのコードがあるようだ。 SOCDEV_PA,SOCDEV_VAは1Mバイトのアライメントで64Mバイトをマップするようだ。 結局は64Mバイトアラインということなのだが。下に書いてあるが、これはsetttb するまでしか使えない。

MMUを理解するために図を書いてみた。

文字を出力するようにしてデバッグしていたところsetttb()まで進んでいる事が 確認できた。ここでなぜ落ちるのかな。。。

setttbするとlocoreで一時的に設定したmapが効かなくなるのが理由だった。 bus_space_mapしてbus_space_write_1すればOKだった。

コンソールが設定されてシリアルコンソールが使えるようになった後のUARTは 入力は必要ないのと、割り込みはバスの初期化でコントローラが設定された 以降でないと使えないため、割り込みを使わずにビジーウェイトで動いている。

void morimoridebug(int c);
void morimoridebug(int c)
{
        uint8_t* uart_base_addr=(uint8_t*)0x1e840000;
        *(uart_base_addr) = c;
}

void morimoridebug(int c);
void morimoridebug(int c)
{
        bus_space_tag_t bst;
        bus_space_handle_t bsh;

        bst = fdtbus_bs_tag;
        bus_space_map(bst, 0x1e840000, 0x100, 0, &bsh);
        bus_space_write_1(bst, bsh, 0, c);
        bus_space_unmap(bst, bsh, 0x100);
}

cninit()のところで落ちる。いろいろ調べたらns8250の実体が無いのが原因だった。 __attribute__((weak))で宣言してあって、uart_ns8250がoptionで指定されていな かったことが原因と思われる。

FDTのシリアルコンソールの設定は以下のようにしておこなわれるようだ。

dtsファイルでchosenで指定されているかserial0なデバイスがチェックされる。

                serial0: serial@40000 {
                        compatible = "ns16550";
                        reg = <0x40000 0x20000>;
                        interrupts = <1>;
                        reg-shift = <2>;
                        clock-frequency = <1000000>;
                        current-speed = <38400>;
                        interrupt-parent = <&PIC>;
                };

そのデバイスのcompatibleがカーネル内でUART_FDT_CLASS_AND_DEVICEで定義されて いるキーワードと一致している物を探す。下記はdev/uart/uart_dev_ns8250.c の定義で、上記のcompatibleと一致しているので、uart_ns8250_classが使われる。

static struct ofw_compat_data compat_data[] = {
        {"ns16550",             (uintptr_t)&uart_ns8250_class},
        {NULL,                  (uintptr_t)NULL},
};
UART_FDT_CLASS_AND_DEVICE(compat_data);

dtbの内容はdtcに含まれるfdtgetで確認できる。

% fdtget -l sample.dtb /
% fdtget -p sample.dtb /
% fdtget sample.dtb /ahb0@1E800000/serial@40000 compatible
0x40000000SDRAM
0x1F0000000x1F7FFFFFFlash
0x19C000000x1E7FFFFFAHB
0x19C000000x191FFFFFStatic/SDRAM Memory Controller
0x19C400000x19C5FFFFInterrupt Controller
+0x00Intr Source Control Reg. 0
+0x80Intr Vector Reg. 0
+0x100IRQ Vector Reg.
+0x104Intr Status Reg.
+0x108Intr Pending Reg.
+0x10cIntr Mask Reg.
+0x114Intr Enable Command Reg.
+0x118Intr Clear Command Reg.
+0x11cIntr Set Command Reg.
+0x124Test mode Reg.
0x19C600000x19C7FFFFAHB Arbiter
0x19C800000x19C9FFFFMAC0
0x19CA00000x19CBFFFFMAC1
0x19ce00000x1DCDFFFF(64M)PCI MEMORY
0x1dce00000x1E4DFFFF(8M)PCI IO
0x1e4e00000x1E6DFFFF(2M)PCI BR
0x1E7000000x1E71FFFFDMA
0x1E8000000x1EFFFFFFAPB
0x1E8000000x1E81FFFFTimer 0/1/2/3
0x1E8200000x1E83FFFFRTC
0x1E8400000x1E85FFFFUART 0
0x1E8600000x1E87FFFFUART 1
0x1E8800000x1E89FFFFSPI
0x1E8A00000x1E8BFFFFGPIO
0x1E8C00000x1E8DFFFFWDT
0x1E8E00000x1E8FFFFFSCU
0x1E9400000x1E95FFFFACI0(PL040)
0x1E9600000x1E97FFFFACI1(PL040)

リセット0x00000000
未定義命令0x00000004
ソフトウエア例外0x00000008
プリフェッチアボート0x0000000C
データアボート0x00000010
IRQ0x00000018
FIR0x0000001C
    
0SPI
1UART0
2UART1
3TIMER0
4TIMER1
5TIMER2
6RTC
7MAC0
8MAC1
9UDC

起動ログログ

なぜかMIPSなビルドに比べるとカーネルはあまり変わりないですが、ファイルシステム のisoの圧縮があまり小さくなっていません。

Buffalo_WZR2-G300N_kernel.kbin3074980 29%ARM
Buffalo_WZR2-G300N_kernel.kbin.oldlzma1061979
Buffalo_WZR2-G300N_rootfs_clean.iso11237376 38%
Buffalo_WZR2-G300N_rootfs_clean.iso.ulzma4311552
Planex_MZK-WNH_kernel.kbin3644076 29%MIPS
Planex_MZK-WNH_kernel.kbin.oldlzma1054388
Planex_MZK-WNH_rootfs_clean.iso12185600 25%
Planex_MZK-WNH_rootfs_clean.iso.ulzma3078144

なぜか圧縮されたカーネルがbootの下にあった事が原因だった。

Flashがprobeされるがデータが見えない状態で、調べたところCFIモードから復帰する 時に0xffを書いているのだが、0xf0(MXのデータシートではRESET)だとうまくいった。 CFIのドキュメントにも0xffか0xf0と書いてあって、どうするのがいいのかな。 ハンドパワーでCFIした結果

5VT1310-EVB# md 0x1f000000
1f000000: ea000016 e59ff014 e59ff014 e59ff014    ................
1f000010: e59ff014 e59ff014 e59ff014 e59ff014    ................
1f000020: 40380180 403801e0 40380240 403802a0    ..8@..8@@.8@..8@
1f000030: 40380300 40380360 403803c0 deadbeef    ..8@`.8@..8@....
1f000040: 1e8e000c 19c04000 19c08000 19c09000    .....@..........
1f000050: 40380000 40380000 4038c064 40394000    ..8@..8@d.8@.@9@
1f000060: e10f0000 e3c000df e3800013 e129f000    ..............).
1f000070: eb000033 e24f007c e51f1030 e1500001    3...|.O.0.....P.
1f000080: 0a000007 e51f2038 e51f3038 e0432002    ....8 ..80... C.
1f000090: e0802002 e8b007f8 e8a107f8 e1500002    . ............P.
1f0000a0: dafffffb e51f005c e2400601 e2400c01    ....?.....@...@.
1f0000b0: e240d00c e51f0064 e2800004 e51f1068    ..@.d.......h...
1f0000c0: e3a02000 e5802000 e2800004 e1500001    . ... ........P.
1f0000d0: 1afffffb e51f008c e3a01101 e1500001    ..............P.
1f0000e0: 0a000009 e24f20ec e24f30b8 e0432002    ..... O..0O.. C.
1f0000f0: e2822004 e3a03101 e0822003 e4904004    . ...1... ...@..
5VT1310-EVB# mw.w 0x1f0000aa 0x98
5VT1310-EVB# md 0x1f000000
1f000000: 0000ffff ffff0000 ffff0000 ffffffff    ................
1f000010: 0000ffff ffff0000 0000ffff 00000000    ................
1f000020: 00520051 00020059 00400000 00000000    Q.R.Y.....@.....
1f000030: 00000000 00270000 00000036 00040000    ......'.6.......
1f000040: 000a0000 00050000 00040000 00160000    ................
1f000050: 00000002 00000000 00070002 00200000    .............. .
1f000060: 003e0000 00000000 00000001 00000000    ..>.............
1f000070: 00000000 00000000 ffff0000 ffffffff    ................
1f000080: 00520050 00310049 00000031 00040002    P.R.I.1.1.......
1f000090: 00040001 00000000 c0b50000 0002c0c5    ................
1f0000a0: 00000000 00000000 00000000 ffffffff    ................
1f0000b0: ffffffff ffffffff ffffffff ffffffff    ................
1f0000c0: ffff0000 ffff0000 ffffffff ffff0000    ................
1f0000d0: ffff0000 ffff0000 ffff0000 ffff0000    ................
1f0000e0: ffff0000 00000000 ffff0000 ffffffff    ................
1f0000f0: ffffffff ffff0055 ffff0055 0000ffff    ....U...U.......
5VT1310-EVB# mw.w 0x1f000000 0xf0
5VT1310-EVB# md 0x1f000000
1f000000: ea000016 e59ff014 e59ff014 e59ff014    ................
1f000010: e59ff014 e59ff014 e59ff014 e59ff014    ................
1f000020: 40380180 403801e0 40380240 403802a0    ..8@..8@@.8@..8@
1f000030: 40380300 40380360 403803c0 deadbeef    ..8@`.8@..8@....
1f000040: 1e8e000c 19c04000 19c08000 19c09000    .....@..........
1f000050: 40380000 40380000 4038c064 40394000    ..8@..8@d.8@.@9@
1f000060: e10f0000 e3c000df e3800013 e129f000    ..............).
1f000070: eb000033 e24f007c e51f1030 e1500001    3...|.O.0.....P.
1f000080: 0a000007 e51f2038 e51f3038 e0432002    ....8 ..80... C.
1f000090: e0802002 e8b007f8 e8a107f8 e1500002    . ............P.
1f0000a0: dafffffb e51f005c e2400601 e2400c01    ....?.....@...@.
1f0000b0: e240d00c e51f0064 e2800004 e51f1068    ..@.d.......h...
1f0000c0: e3a02000 e5802000 e2800004 e1500001    . ... ........P.
1f0000d0: 1afffffb e51f008c e3a01101 e1500001    ..............P.
1f0000e0: 0a000009 e24f20ec e24f30b8 e0432002    ..... O..0O.. C.
1f0000f0: e2822004 e3a03101 e0822003 e4904004    . ...1... ...@..
5VT1310-EVB# 

cfid0のデータが読めるようになったのでdtsにpartitionのregを設定して、rootfsを マウントできるようにしたところ、マウント後に固まるようになった。これは割り込み ルーチンがダミーのままでちゃんと作ってなったためだったので、コードを書いてみた。 RT1310の割り込みは32本しか無く、かなり簡単なコードですんだ。

Flashが見えるようになったのでどうにかrootfsのマウントまで進んだが、rc.d/MAINの md0をnewfsしているところで固まる。なんでだろう。。。

newfsで固まるのは、時間の処理が正常に動いていないためselectがだんまりになって いるためのようだった。 armv4系ではtimerルーチンはそれぞれ実装になっていてRT1310も作ってみたが、それが ちゃんと動いていないのかと思ったが、作った当時はそれなりに動いている事は確認 していたと思う。 よくよく確認してみるとdateコマンドで時間が全く変化しない。 sysctlのkern.cp_timeやcp_timesも変化しない。kern.timecounterのcounterは インクリメントしているしeventtimerの割り込みもデバッグライトで確認できている のだが。。。 で調べてみたところ全く動いていないわけではなくタイマー側は 動いているがカーネルさんがちゃんとしてくれていないような感じだった。 前に調べていた 時間の処理をもう一度調べなおして、ソースを確認したところ DEVICE_POLLINGというオプションがありmips系は設定されていなかったのだが、 ZRouterのarmなixpでは設定されていて、それからコピーしたRT1310でも設定されて いたので外してみたところ、dateは時間は進むようになった。ところが時間の進み方が 10秒単位だったりする。。。

とりあえずこの状態で、シングルユーザからマルチユーザに移ると、ときどきnewfsが 成功して、loginプロンプトが出るが今度はInvalid argumentでログインできない。 シングルユーザでsttyでttyu0のボーレートを設定すると同じようにエラーになる。 FDTの値が正しくなくて起動時はエラーで設定されずU-Bootのボーレートがそのまま んになるので、使えていたみたいだ。^ ^;

UARTのコードはクロックとボーレートから分周比を出して、それが範囲外だったり 分周比からボーレートを出して元のボーレートとのずれが大きい場合にEINVALを返す。

UARTのクロックはいろいろ試して判明しました。

時間が10秒毎に進む件を調べていてSCHED_ULEからSCHED_4BSDに変更したら、まったく 時間が進まなくなりました。^ ^; newfsはなぜか起動後10分くらいしてから マルチユーザに移行するとうまくいったりする。random: unblocking device.が 出た後だとほぼうまくいく。謎だ。

タイマーの使い方がまずくてeventtimerの割り込みが上がっていないのが原因だった。 割り込みがなくても時間はちゃんと進む事にびっくり。

Etherのドライバは二日くらいでどうにか動くようになった。AR2315と同じTulip系 だったが、AR2315ではMACアドレスをCSRで設定していたが、こちらはsetup frame での設定だったのでdev/dcのコードを参考に追加してみた。あと違いはCSRが8バイト バウンダリだったのとエンディアンが違ったくらいだった。

このボードにはIP175CがのっていてEthernetSwitchにコードがあったので、試して みたがmiiのコードを用意して、mdio周りをいろいろいじってどうにか認識できたが ときどき固まるので、外してしまった。miiのアクセスがCSRのビット操作で EthernetSwitchのポーリングと相性が良くないのかもしれない。 Switchのポートの状態の監視のためのポーリングだと思うが無くても問題はないので 外せれば良いのだが。

レビュー出しました。 ターゲットがあまりないので採用されるかはわからないですが。

レビューはす進んでいないが、どきどきビルドを通して焼いているが、特に問題は 起きていない。(2017/02/22)

upgradeコマンドでcfiがアップデートできない。コマンドは終了するのだが、実際には 書き込まれていない。何故かな。。。(2017/02/22)



Copyright (C) 2015 Hiroki Mori All Rights Reserved.