eCosをQEMU上で動かす

0.背景
---------------------------------------------------------
前回の「eCosの環境を作成する」の第2弾、QEMU上で動作させられたので、備忘録。
https://qiita.com/aklak/items/3d82710837961ca19f59

１．環境
---------------------------------------------------------
HOST OS:Windows10

２．動作手順
---------------------------------------------------------

１．QEMUをDLする。
qemu version：Qemu-0.12.2-windows-Lite
以下のサイトでdlした。(http://lassauge.free.fr/qemu/)
http://lassauge.free.fr/qemu/release/?M=D
Qemu-0.12.2-windows-Lite.zip

展開して、Windowsの環境変数設定して、コマンドプロンプトで以下のコマンドを実行
qemu -boot a -fda redboot_pc_rltk8139.flp -net nic,model=rtl8139 -net user -redir tcp:9001::9000

redboot_pc_rltk8139.flpはredbootのバイナリファイルをddコマンドでfloppy化したもの

以下にRedbootのbuild手順を示す。
事前準備
ecos3.0の環境を作成しておく(DL時にGNU Toolを選択するところでi386-elfを選んでおく+PATHも通す）


本番
ecosのサイトへいき最新版をDLする。
/opt/ecosにDL
方法は以下を参照
http://ecos.sourceware.org/anoncvs.html

export ECOS_REPOSITORY = /opt/ecos/ecos/packages
ecosconfig new pc_rltk8139 redboot
ecosconfig import $ECOS_REPOSITORY/hal/i386/pc/current/misc/redboot_FLOPPY.ecm
ecos.eccの以下を編集
cdl_component CYGSEM_REDBOOT_DISK_IDE {
      user_value 0
  };
ecosconfig tree
make
FloppyDisk化
dd if=install/bin/redboot.bin of=redboot_pc_rltk8139.flp conv=notrunc,sync count=1 bs=＄(( 1024*10*144 ))
redboot_pc_rltk8139が作成完了
  
参考サイト
http://www.codeconfidence.com/technote-0002.shtml

以下は「http://tickling.bitbucket.org/ecosonqemu.txt」のそのまま
Booting eCos(R) with RedBoot on QEMU emulator
\=============================================

QEMU's version
\--------------

I worked with

  \\$ qemu -version
  QEMU PC emulator version 0.12.3 (qemu-kvm-0.12.3), Copyright (c) 2003-2008 Fabrice Bellard

My CPU does not support KVM, so, to do not paste warnings then I used

  \\$ alias qemu='/usr/bin/qemu -no-kvm'

QEMU's NICs
\-----------

  \\$ qemu -net nic,model=?
  qemu: Supported NIC models: ne2k_pci,i82551,i82557b,i82559er,rtl8139,e1000,pcnet,virtio
  \\$

It's good to know that RealTek RTL8139 is a supported NIC by QEMU as
eCos has an ajective target, that's 'pc_rltk8139'. Export below

  $ export TARGET=pc_rltk8139

Build RedBoot
\-------------

First, let's build RedBoot for the target

  ecosconfig new \\$TARGET redboot &&
  ecosconfig import \\$ECOS_REPOSITORY/hal/i386/pc/*/misc/redboot_FLOPPY.ecm &&
  ecosconfig import /dev/stdin << EOF &&
  cdl_component CYGSEM_REDBOOT_DISK_IDE {
      user_value 0
  };
  EOF
  ecosconfig tree &&
  make -s

NOTE: I need no IDE disks.

Create Floppy Image
 -------------------

What 1.44M Floppy is?
 ~~~~~~~~~~~~~~~~~~~~~
  \\$ tclsh
  % format {%1$d or %1$#x} [expr int(1024*1000*1.44)]
  1474560 or 0x168000
  % exit
  \\$ dd if=install/bin/redboot.bin of=redboot_pc_rltk8139.flp conv=notrunc,sync count=1 bs=\\$(( 1024*10*144 ))
  0+1 records in
  1+0 records out
  1474560 bytes (1.5 MB) copied, 0.00805096 s, 183 MB/s
  \\$
  \\$ ls -l *.flp
-rw-r--r-- 1 sg sg 1474560 2010-07-07 16:31 redboot_pc_rltk8139.flp
  \\$



Testing RedBoot
　---------------

  $ qemu -S -boot a -fda redboot_pc_rltk8139.flp -net nic,model=rtl8139 -net user,hostfwd=tcp:127.0.0.1:9001-:9000 -nographic -serial pty
  char device redirected to /dev/pts/1
  QEMU 0.12.3 monitor - type 'help' for more information
  (qemu) _

[NOTE]
-S              freeze CPU at startup (use 'c' to start execution)


  $ minicom -o -D /dev/pts/1 -p pts/1

  (qemu) c

Then, in minicom you have to see something like this

  +Ethernet eth0: MAC address 52:54:00:12:34:56
  IP: 10.0.2.15/255.255.255.0, Gateway: 10.0.2.2
  Default server: 0.0.0.0
  
  RedBoot(tm) bootstrap and debug environment [FLOPPY]
  Non-certified release, version UNKNOWN - built 16:27:59, Jul  7 2010
  
  Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
  Free Software Foundation, Inc.
  RedBoot is free software, covered by the eCos license, derived from the
  GNU General Public License. You are welcome to change it and/or distribute
  copies of it under certain conditions. Under the license terms, RedBoot's
  source code and full license terms must have been made available to you.
  Redboot comes with ABSOLUTELY NO WARRANTY.
  
  Platform: PC (I386) 
  RAM: 0x00000000-0x000a0000 [0x0008a030-0x000a0000 available]
  RedBoot> _

  $ telnet localhost 9001
  Trying ::1...
  Trying 127.0.0.1...
  Connected to localhost.
  Escape character is '^]'.
  RedBoot> _

  RedBoot> ping -v -h 10.0.2.2
  Network PING - from 10.0.2.15 to 10.0.2.2
   seq: 1, time: 0 (ticks)
   seq: 2, time: 0 (ticks)
   seq: 3, time: 0 (ticks)
   seq: 4, time: 0 (ticks)
   seq: 5, time: 0 (ticks)
   seq: 6, time: 0 (ticks)
   seq: 7, time: 0 (ticks)
   seq: 8, time: 0 (ticks)
   seq: 9, time: 0 (ticks)
   seq: 10, time: 0 (ticks)
  PING - received 10 of 10 expected
  RedBoot> _

  $ i386-elf-gdb -q -nx
  (gdb) target remote localhost:9001
  Remote debugging using localhost:9001
  0x0000be58 in ?? ()
  (gdb) detach
  (gdb) _

  $ i386-elf-gdb -q -nx
  (gdb) target remote /dev/pts/1
  Remote debugging using /dev/pts/1
  0x0000be58 in ?? ()
  (gdb) _

Testing 'http1'
　--------------

  qemu -S -boot a -fda redboot_pc_rltk8139.flp -net nic,model=rtl8139 -net user,hostfwd=tcp:127.0.0.1:9001-:9000,hostfwd=tcp:127.0.0.1:8080-:80 -nographic -serial pty
  char device redirected to /dev/pts/1
  QEMU 0.12.3 monitor - type 'help' for more information
  (qemu) _

  $ minicom -o -D /dev/pts/1 -p pts/1

  (qemu) c
  (qemu) _

  ecosconfig new pc_rltk8139 net &&
  ecosconfig add httpd
  ecosconfig import /dev/stdin << EOF &&
  cdl_option CYGPKG_NET_MAXSOCKETS {
      user_value 32
  };
  EOF
  ecosconfig tree &&
  make -s &&
  make -C net/httpd/* tests

.gdbinit
  rbreak cyg_assert_fail
  rbreak cyg_test_exit
  target remote localhost:9001
  load


.GDB session
  (gdb) detach
  (gdb) target remote /dev/pts/1
  (gdb) set $pc=_start
  (gdb) continue


// vim: syntax=asciidoc: textwidth=70:

3．実行手順(デバックテスト編)
----------------------------
ECOS_REPOSITORYの参照先をローカルディレクトリにする。
  export ECOS_REPOSITORY=/home/ユーザ名/ecos/ecos/packages
  mkdir -p build_pc_ecos_apl
  cd build_pc_ecos_apl
  ecosconfig new pc_rltk8139 net &&
  ecosconfig add httpd
  以下を編集する。
  cdl_option CYGPKG_NET_MAXSOCKETS {
      user_value 32
  };
  EOF
  ecosconfig tree &&
  make -s &&
  make -C net/httpd/* tests

  ホストから下記のGDBコマンドを実行し、Webアプリテストを実施する。
  とりあえず、ユーザアプリの実行のみを行った。
  i386-elf-gdb -q -nx install/tests/net/httpd/current/tests/httpd1
  (gdb) target remote localhost:9001
  Remote debugging using localhost:9001
  0x0000be60 in ?? ()
  (gdb) load
  Loading section .text, size 0x38e0a lma 0x108000
  Loading section .rodata, size 0x4044 lma 0x140e10
  Loading section .data, size 0x1c68 lma 0x144e58
  Start address 0x108000, load size 256694
  Transfer rate: 107 KB/sec, 322 bytes/write.
  (gdb) detach
  Ending remote debugging.
  (gdb) target remote /dev/pts/19
  Remote debugging using /dev/pts/19
  0x0000be60 in ?? ()
  (gdb) set $pc=_start
  (gdb) continue
  Continuing.
  [cyg_net_init] Init: mbinit(0x00000000)
  [cyg_net_init] Init: cyg_net_init_devs(0x00000000)
  Init device 'rltk8139_eth0'
  [cyg_net_init] Init: loopattach(0x00000000)
  [cyg_net_init] Init: ifinit(0x00000000)
  [cyg_net_init] Init: domaininit(0x00000000)
  [cyg_net_init] Init: cyg_net_add_domain(0x00146520)
  New domain internet at 0x00000000
  [cyg_net_init] Init: cyg_net_add_domain(0x00145c60)
  New domain route at 0x00000000
  [cyg_net_init] Init: call_route_init(0x00000000)
  [cyg_net_init] Done
  BOOTP[eth0] op: REQUEST
         htype: Ethernet
          hlen: 6
          hops: 0
           xid: 0x12243456
          secs: 0
         flags: 0x8000
         hw_addr: 52:54:00:12:34:56
       client IP: 0.0.0.0
           my IP: 10.0.2.15
       server IP: 10.0.2.2
      gateway IP: 0.0.0.0
    options:
          DHCP message: 3 REQUEST
          DHCP server id: 10.0.2.2
          subnet mask: 255.255.255.0
              gateway: 10.0.2.2
        domain server: 10.0.2.3
          DHCP time 51: 86400
          DHCP option: 37/55.9: 54 51 58 59 1 3 6 15 28
          DHCP option: 39/57.2: 576
          DHCP requested ip: 10.0.2.15
  Route - dst: 0.0.0.0, mask: 0.0.0.0, gateway: 10.0.2.2
  PASS:<httpd test finished>
  EXIT:<done>

  q
  ^C
  Program received signal SIGINT, Interrupt.
  [Switching to Thread 6]
  0x0010f3c7 in cyg_test_exit ()
      at /home/reki/ecos/ecos/packages/infra/current/src/tcdiag.cxx:254
  254	cyg_test_exit(void)
  (gdb) detach
  Ending remote debugging.
  (gdb) q

実行テストができたので、あとは自前でmakefileでeCos用のバイナリを作成すればok.
バイナリの作成例は以下にある。
/opt/ecos/ecos-3.0/examples
RTOSなのでクロスツールの設定は当然として、eCosとして大事なことは以下。(examplesのmakefileなどから十分読み取れるが、念のため記載）
１．/ecos/ecos/package以下のをソースコードをecosconfig treeしたディレクトリへヘッダーとmakefileなどのexportをする。
２．exportしたディレクトリでmakeしてlibtarget.aを作成する。
３．eCos applicationはlibtarget.aとtarget.ldをlinkしてバイナリ作成する。