by shigemk2

当面は技術的なことしか書かない

ARM 64bit has come! #kernelvm

こばやしてつじ こばやしてつゆき

@testu_koba

ARM 64bit

  • 仕様書みて、拾ってって、興味のあるところを淡々と紹介してく
  • QEMUでaarch64試してみよう

そのアーキテクチャ

の3ページめ

ARM命令SUM命令は動く ARM命令Thumb命令は動く

2つの命令セットがあって切り替えて使うことが出来る。

過去の命令セットアーキテクチャの上位互換である、という説明。

インストラクションセット(命令セット)はA64

ARM64は正式名ではない

arch/arm64

arch/aarch64が最初のカーネルパッチで名前がださいからarm64に変わった「今ならまだ間に合う!」

4 levels

Typical usage

  • EL0 User application
  • EL1 kernel of os
  • EL2 hypervisor (v8から)
  • secure monitir

アドレス空間の切り替え

レジスタってどうなってるの

R0-R30 64bitの長さの汎用レジスタが、ある

Wn lower 32bit(32ビット演算用) Xn 64bit

  • (なんで31個しかないの)
  • 32個めのレジスタは汎用レジスタではない

SP or 0レジスタ

スタックポインタとかが汎用レジスタとは別扱い

JUMP命令 SWITCH文などトリッキーな書き方が出来る これはいままでの話。できなくなった。

プログラムカウンタを計算の出力先としては使えない(アグレッシブモードとかあるんで使うぶんには困らない)

プログラムカウンタを計算の出力先としては使えない(PC relativeのアドレッシングモードとかあるんで使うぶんには困らない)

素直な体系

V0-V31

128bitのレジスタ(浮動小数点用のレジスタ)

FPU - Wikipedia

Scalar(Bn,Hn,Sn,Dn,Qn) Vector(Vn.8B, Vn.16B)

x86と同等の計算精度となった

addressing model

仮想アドレス空間は64bit

物理アドレス空間と仮想アドレス空間の違いとその基礎知識 : Web Memo.SE

tagはソフトで自由に使える

動的型付け言語のように、型をアドレスの一部に書き込んでおく

68000みたいな使い方で、マスクするより早い運用が可能であったけど、 所詮は24bitだったので…

使えるからってジャカジャカ使ってると互換性を損なう

8bit tag + 56bit virtual addressの組み合わせ。これが枯渇するのはまだまだ先ではないかと

Calling Standard

  • R30 = LR
  • R29 = FP

  • R0-R7 はInteger or pointer

  • V0-V7 はFloat

レジスタは壊れる IP0(R16), IP1(R17)はリンカが生成するコードがアドレス計算に使うので、関数呼び出しのときに壊れる

A64命令セット

いろいろ研究が進んでおり、建て増し的なアーキテクチャからの脱却が進められている

そんなに不便はない

面倒なところはすっぱり忘れた命令セットになった

汎用レジスタのロードがなくなった(LDP/STPは例外) 汎用レジスタを一度に複数個ロードする命令がなくなった(LDP/STPは2つレジスタを指定できる)

Thumb-2 ‐ 通信用語の基礎知識

YIELD instruction

NOP命令で、大して重要じゃない奴

同じ状態だと、x86では苦し紛れに次のアドレスへジャンプとかやるらしいけど、ARM64は命令が存在する

サンプル

(コードを書く→アセンブル→逆アセンブル)

#include <stdio.h>

int main()
{
  int i;
  for (i = 5; i >= 0; i--) {
    printf("count down: %d\n", i);
  }
  return 0;
}

逆アセ結果は64bit

stpでスタックに退避してる

浮動小数点比較

Thumb2だと一旦コピーしないといけない

Thumb2だとFPUのフラグを一旦コピーしないといけない

A64だと直接比較ができる

maxとかminとかド直球の命令は存在するけど、実用には至っていない

Cache control

Application level cache instructions

Data cache

  • DC VAU
  • DC CVAC
  • DC CIVAC

Instruction Cache

書いたときにはデータとして扱われている

データキャッシュをメモリに吐き出し、もう一度読み込む

今まではシステムコールが存在して、カーネルがそれをやっていた。

V8からはデータキャッシュ、命令キャッシュを直接ごにょごにょできる命令が出来た。

http://ja.wikipedia.org/wiki/%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%82%B3%E3%83%BC%E3%83%AB:titile

命令をロードしたり生成したりする

実行時コンパイラ - Wikipedia

Preloading cache

予めキャッシュにロードしとけよ

何が起こるかはSOCの実装定義を見るべし

System-on-a-chip - Wikipedia

Non-temporal load/store

LDNP/STNP

メモリの最適化、チューニング

Aarch32

  • Upper compatible with ARMv7

aarch64で削除されたモードがある

Jazelle(Javaを書くときに猛威をふるったやつ), ThumbEE(Jazelleの代わり)

Qemuがサポートしないし、誰も使わなかったので削除された

Qemuで動かしてみよう

Qemuは aarch64 user modeが使える

なので、Ubuntu 14.04以降だとapt-getでごにょごにょできる。

(gdbとかは自分でコンパイルしないといけないけど手順は楽)