3DSにおけるプロセス間通信
今回はプロセス間通信(IPC)を用いて、ホームボタンを押す処理をGatewayコードで実装してみる。
仕組み
IPCのリクエストが行われると、リクエスト内容がスレッドローカルストレージという場所の0x80番地に書き込まれる。これがSendSyncRequestと呼ばれるsvc命令によってサーバーに送信される。サーバーがリクエスト内容を受け取ることによってはじめてリクエストが成立する。
以上を踏まえて、今回行う手順は次の通りである。
- スレッドローカルストレージの0x80番地に「ホームボタンを押す」という処理にあたるIPCコマンドを書き込む。
- svcSendSyncRequestでリクエストをサーバーへ送信する。
完成したコード
[Force Home Button] F0F00000 00000024 // 0x24byte EE1D2F70 E1CF01D0 E1C208F0 E59F0004 EF000032 E12FFF1E 00020003 000C0080 00000204 00000000
解説
処理内容としては以下の通り。
EE1D2F70 mrc 15, 0, r2, cr13, cr0, 3 E1CF01D0 ldrd r0, [pc, #0x10] E1C208F0 strd r0, [r2, #0x80] E59F0004 ldr r0, [pc, #4] EF000032 svc #0x32 E12FFF1E bx lr 00020003 .word 0x20003 000C0080 .word 0xC0080 00000204 .word 0x204
mrc 15, 0, r2, cr13, cr0, 3
スレッドローカルストレージへのポインタをr2に読み込む。ここにIPCコマンドを格納することになる。
ldrd r0, [pc, #0x10]
r0に0xC0080を、r1に0x204を読み込む。ホームボタンを押した際の処理は、PublishToSubscriberによって通知IDが送信されることで成立する。ここで、0xC0080はPublishToSubscriberのコマンドヘッダ、0x204はホームボタンを押した際の通知IDにあたる。
strd r0, [r2, #0x80]
r0・r1の値をr2+0x80の位置に格納する。r2+0x80は、スレッドローカルストレージ内のIPCコマンドを格納する場所にあたる。
ldr r0, [pc, #4]
0x20003をr0に読み込む。svc命令を使用する際には、予め指定されたレジスタに引数となる値を格納しておく必要がある。SendSyncRequestを使用する場合は0x20003をr0に代入しておく。
svc #0x32
3DSでは、svc命令の0x32番がSendSyncRequestにあたる。これによりスレッドローカルストレージに格納したIPCコマンドが送信される。
bx lr
サブルーチンの終了。lrに格納されているアドレスへと分岐する。
参考文献: 3dbrew