2010年01月06日

QEMUメモ(1)

少し前にqemuのソースを追いかけたときのメモを放出します。

TCG

qemuは高速に実行するためにインタプリタでなくJITのようにターゲットのCPU命令列をホストのCPU列に変換して実行する。 version 0.10の頃からこの部分が従来のトランスレータからTCG(Tiny Code Generator)と呼ばれるものに置き換えられた。



TCGの概要

ターゲットの命令コードからホストの命令コードに変換する時に一度中間コードを生成する。

つまり、変換は

  • ターゲットの命令コード -> 中間コード
  • 中間コード -> ホストの命令コード

の2段階になる。

(原理的にはその間に中間コード->中間コードの最適化のパスを追加することが可能。)

このように中間コードを介すことで、サポートするターゲットCPUを追加する時にはそのターゲットの命令コードから中間コードを生成する部分を追加すればよい。

qemuの最新のソースアーカイブでは以下のものが、ターゲット、ホストのコードが存在する。(完成度については不明)

  • target: alpha, arm, cris, i386, m68k, microblaze, mips, ppc, sh4, sparc
  • host: arm, hppa, i386, ppc, ppc64, sparc, x86_64

ライセンス

QEMUは全体としてはGPL

libqemu.a はLGPL

多くのハードウェアデバイスエミュレーションのコードはBSDライセンスでリリースされている。

TCGが関連するところとしては

  • ターゲットの命令コードを中間コードに変換する部分はLGPLv2

(ソースアーカイブの中のtarget-xxx のディレクトリ)

  • 中間コードをホストの命令コードに変換して実行する部分はBSD likeライセンス

(ソースアーカイブの中のtcg以下のディレクトリ)

TCGの利点

従来のトランスレータと比較して、

  • GCCのversionに依存しなくなった。従来のトランスレータはgcc3.xの生成するコードに依存していた。
  • 中間コードのレベルでpeep hole optimizeがかけられるので若干の実行性能向上がある。

ソースコードの入手

gitリポジトリ

http://savannah.nongnu.org/git/?group=qemu

Ubuntu9.04 desktop x86_64の上で問題なくビルドできる。

libqemu.a

armでlibqemu.aには以下のファイルが含まれる。

 ar rcs libqemu.a
  exec.o
  translate-all.o
  cpu-exec.o
  translate.o
  host-utils.o
  tcg/tcg.o
  tcg/tcg-runtime.o
  fpu/softfloat.o
  op_helper.o
  helper.o
  neon_helper.o
  iwmmxt_helper.o
  disas.o
  arm-dis.o
  i386-dis.o

その他

現時点でのTCGではFPU命令を直接はサポートしていない。FPU命令はターゲットの命令コードから中間コードに変換する段階でヘルパー関数を呼び出すようなコードに変換されるらしい。

AndroidのSDKのシミュレータはqemuの0.8.2(古いトランスレータ)を使っていた。そのためソースディストリビューションにはprebuildされたgcc3がついてきた。現在ではTCGを使うようにアップデートされている。ただしqemuのソースリポジトリの最新版には追いついていない。

libqemu.a 調査メモ

libqemu.a が提供するインタフェース (export)

qemu-system-armをビルドした時にわざとlibqemu.aをはずしてリンクエラーを起こさせ、そのときに報告されたundefined referenceをまとめてみた。以下の関数またはグローバル変数がlibqemu.aの外から使用されている。

 arm_cpu_list
 cpsr_read
 cpsr_write
 cpu_abort
 cpu_arm_exec
 cpu_arm_init
 cpu_arm_set_cp_io
 cpu_breakpoint_insert
 cpu_breakpoint_remove
 cpu_breakpoint_remove_all
 cpu_dump_state
 cpu_exec_init_all
 cpu_exit
 cpu_get_physical_page_desc
 cpu_interrupt
 cpu_log_items
 cpu_memory_rw_debug
 cpu_physical_memory_map
 cpu_physical_memory_reset_dirty
 cpu_physical_memory_rw
 cpu_physical_memory_set_dirty_tracking
 cpu_physical_memory_unmap
 cpu_physical_memory_write_rom
 cpu_physical_sync_dirty_bitmap
 cpu_register_io_memory
 cpu_register_map_client
 cpu_register_physical_memory_offset
 cpu_reset
 cpu_reset_interrupt
 cpu_set_log
 cpu_set_log_filename
 cpu_single_env
 cpu_single_step
 cpu_str_to_log_mask
 cpu_unregister_io_memory
 cpu_watchpoint_insert
 cpu_watchpoint_remove
 cpu_watchpoint_remove_all
 dump_exec_info
 first_cpu
 last_ram_offset
 ldl_phys
 ldq_phys
 lduw_phys
 logfile
 monitor_disas
 phys_ram_dirty
 qemu_cpu_has_work
 qemu_get_ram_ptr
 qemu_icount
 qemu_ram_alloc
 qemu_register_coalesced_mmio
 qemu_unregister_coalesced_mmio
 stl_phys
 stl_phys_notdirty
 stw_phys
 syminfos
 tb_flush
 use_icount

libqemu.a が利用しているインタフェース (import)

libqemu.aとダミーのmainだけでリンクしたときに報告されたundefined reference をまとめてみた。libqemu.aを使うときには以下の参照(関数かグローバル変数かはこれだけではわからない)を用意する必要がある。

 armv7m_nvic_acknowledge_irq
 armv7m_nvic_complete_irq
 armv7m_nvic_set_pending
 cpu_load
 cpu_save
 do_arm_semihosting
 gdb_register_coprocessor
 monitor_printf
 monitor_vprintf
 pstrcpy
 qemu_cpu_kick
 qemu_cpu_self
 qemu_free
 qemu_init_vcpu
 qemu_malloc
 qemu_mallocz
 qemu_memalign
 qemu_realloc
 qemu_vmalloc
 ram_size
 register_savevm
 semihosting_enabled
 singlestep
 vmstate_info_uint32
 vmstate_register


トラックバックURL

トラックバック一覧

1. クロス開発でのQEMU まとめ(基礎編)  [ KMC Staff Blog ]   2010年09月16日 11:08
ここまでのQEMUの記事のリンク集です。 なお、CELFテクニカルジャンボリーにて、時間をいただきましたので、このあたりについて話をさせていただきます。 (3月5日 中野サンプラザ 入場無料) よろしければご参加ください。

コメントする

名前
 
  絵文字
 
 
記事検索
最新コメント
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

QRコード
QRコード