カーネルデバッガ
出荷直前までデバッグをしなければいけないことは普通にある.場合によっては,出荷後も.
現在的なベスト解はJTAG端子を出しておくことのような気もするけれど,丸裸になりすぎるという理由で量産時には端子を殺されてしまうことも多い(気がする).
そういうときのために,余程メモリに余裕が無い場合を除き,デバッガスタブを埋めておくと安心.
デバッガスタブの埋め込み方は,主に2種類ある.
- ブートローダにデバッガ機能を付ける.割込みや例外は,ブートローダが捕捉し,必要に応じ,カーネルに投げる.
- カーネルにデバッガ機能をリンクする.デバッグに必要な一部の割込みや例外は,カーネル管理外の割込みとして利用する.
前者はRedBootが有名.後者はLinuxのkgdbなど.
どちらもデバッグ作業者から見て実現できることはほぼ等価なのだけれども,推奨ブートローダがデバッガ機能を持たない場合は,前者は選べない.例えば,IA32なPC環境で多く用いられているGRUBが使われている時など.
また,RAMが少ない場合,ROMを上手くやりくりしてデバッガとカーネルを分離することはできなくもないけれど,リンクした方が扱いが楽な場合もある.
そんなわけで,カーネルデバッガを作ってみた.コード自身はv850で吠えた時に作ったものの流用.当面はオープンソースにする気は無い.
monacintosh2:OBJS monaka$ /pizza/bin/i386-elf-gdb ./jsp GNU gdb 6.8.50.20080403-cvs Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "--host=i686-apple-darwin9 --target=i386-elf"... (gdb) set remotebaud 19200 (gdb) set debug remote 1 (gdb) target remote /dev/tty.usbserial19 Remote debugging using /dev/tty.usbserial19 &6&+~6g packet: $qSupported#37...putpkt: Junk: 6 Sending packet: $qSupported#37...Packet instead of Ack, ignoring it Packet instead of Ack, ignoring it Sending packet: $qSupported#37...Ack Packet received: Packet qSupported (supported-packets) is NOT supported Sending packet: $?#3f...Ack Packet received: S02 Sending packet: $Hc-1#09...Ack
とか出て,
Sending packet: $m10c85c,4#61...Ack Packet received: 01000000 0x001000b0 in task (exinf=0x1) at sample1.c:130 130 for (i = 0; i < task_loop; i++); (gdb)
めでたしめでたし.
カーネルへのデバッガの埋め込み方は「独自OSを作ってみよう!」が詳しい.でも,KOZOSはsignalを使ったエミュレーションOSのために,却って茨の道を歩んでいる部分もある.