early_printk、printasciiとは

printk()は、printf()と基本的にはやってることが同じで、
call_console_drivers()という関数を内部で呼び、
シリアルコンソールドライバを通して、シリアルのメモリマップIOに、バイト列をwriteする。


カーネルのブート時には、init_IRQ()で、割り込みが有効になるまで、
シリアルコンソールドライバは使えない。
そこで、syslogと共有するバッファに文字列をバッファリングしておいて、
シリアルが使えるようになったら、これをドライバにフラッシュする。


割り込みが有効になるまで、シリアルコンソールドライバが使えない。
early_printk()をつかうと、シリアルのアドレスへ直接、文字を出力してくれる。
これは、カーネルのビルド時のオプションで指定する必要があるが、アーキテクチャによってはなかったりする。
sh、mipsx86には用意されている。
ARM でも,debug.S での printasciiがこれの役割を果たす。


linuxカーネル2.6.27.27:
arch/x86/kernel/early_printk.c


ENTRY(printascii)
addruart r3
b 2f
1: waituart r2, r3
senduart r1, r3
busyuart r2, r3
teq r1, #'\n'
moveq r1, #'\r'
beq 1b
2: teq r0, #0
ldrneb r1, [r0], #1
teqne r1, #0
bne 1b
mov pc, lr

ARMの浮動小数点演算について

EABI,OABIがあり、EABIではデフォルトで-msoft-floatオプションがgccにつく。

EABIはOABIに対して、フロート演算が非常に早い。

とある方のベンチマーク
http://jr0bak.homelinux.net/~imai/pukiwiki/pukiwiki.php?%C6%FC%B5%AD%2F2009-01-12%2F%A5%D9%A5%F3%A5%C1%A5%DE%A1%BC%A5%AF

* OABI ではカーネルの FPU エミュレーション
* EABI ではユーザプログラムでの浮動小数点演算

なぜ違いがでるのか?:
FPUエミュレーションは、カーネルがハードフローに対応しておらず、浮動小数点命令を実行し、
その結果、命令が定義されていない例外が発生したときに、
FPUエミュレーションを例外ハンドラで実行する。
これは、カーネルモード、ユーザモードの行き来があるため非常にオーバヘッドが大きくなる。