ArduinoでBIOSをキーボード操作する

目的

会社のノートPCにて,外付けキーボードをUSB有線からBluetooth無線に切り替えたため,起動時のBIOSパスワードが外付けキーボードから入力できなくなった.もちろん,BIOSパスワード入力時だけUSB有線で接続すれば入力できるが,PC起動時に毎回それをやるのはとにかく面倒なのが事実*1

そこで,Arduino Leonardoもしくはその互換品を使って,BIOSパスワード入力時にそれをPCに接続してBIOSパスワード入力を代行するデバイスを作った例を紹介する.本記事のスクリーンショット等は記事記載当時2018/07/22のものだが,以下の環境にて動作確認済み:

名称 規格 製造会社 備考
オペレーティングシステム Windows 10 Pro 64ビット,バージョン22H2 マイクロソフト 記事記載当時はWindows 7
Arduino Leonardo互換品 CJMCU Beetle 不明 記事記載当時はAliExpressで4.19米ドル
Arduino環境 Arduino IDE 1.8.19 Arduino.cc 記事記載当時のバージョンは1.8.5
Arduino BootKeyboard/Mouse ライブラリー HID-Project 2.8.4 NicoHood 記事記載当時のバージョンは2.4.4

(2021/01/23 20:14メモ)富士通のLIFEBOOKにてBIOS(InsydeH2O)が操作できないことが判明したしました... でも,直し方がわかりません...ほかにもそういう情報がありましたら,もしくはココを変更すると直せますという情報がありましたら,コメント下さい

動作OK/NG 動作確認PC 備考
OK Dynabook G83/KV(型番A6GNKVKCH51A) BIOSメーカー不明
NG LIFEBOOK U9310/D(型番FMVU28011) InsydeH2O BIOS,社内で悪評高い爆熱ブルスク頻発PC
NG HP EliteBook 830 G6 本記事のコメントより
NG HP EliteBook 830 G5 本記事のコメントより

結論

Arduino Leonardo互換品選定

本家,Arduino LeonardoはUSB Micro-Bのコネクター形状ではあるが,毎日BIOSパスワード入力のためだけに接続するには基板が大きすぎる.なるべく小さい基板という要求を満たすべく探し当てたのが,今回使うCJMCU Beetleという互換品.

Arduino Leonardo CJMCU Beetle
https://www.arduino.cc/wiki/static/2ff70e489e19094e062c441e5f5910e9/41099/leonardo.jpg

本記事記載当時は,Amazon.co.jpにて3,500円送料込み(2023/12/16現在リンク切れ)で,AliExpressで4.19米ドル送料込み(2023/12/16現在リンク切れ)*2

2023/12/16現在では,Amazon.co.jpにて2,250円(1,550円,別途送料700円)AliExpressにて1,175円(707円,別途送料468円)が最安値.

Arduinoプログラミング

NicoHood氏によるHID-Projectを利用する.

  1. CJMCU-Beetle開封
     
     
  2. USBポートに挿入する
    自動的にドライバーのインストールが開始し,特に問題なく完了する
     
     
     
  3. ArduinoにてArduino Leonardoとして認識させる
     
     
  4. ArduinoにてCOMポートを正しく設定する
     
     
  5. ArduinoにてライブラリーHID-Projectをインストールする(HIDで検索するとヒットします)
     
     
  6. Arduinoスケッチを記載して,コンパイル&書込,書込終了後に自動的に再度CJMCU-Beetleが認識されてArduinoスケッチが実行される.以下は,USB挿入後に2秒間LEDを点滅させる処理を入れてから012と入力するスケッチ例である
#include "HID-Project.h"

void vBootKeyboardStartup() {
  // after BootKeyboard.begin() invoked, wait about 2 seconds
  // to be stable (it may be less than 2-second)
  const unsigned short usStartupDelay = 2000;
  const unsigned char ucNumOfBlinking = 8;

  BootKeyboard.begin();
  for (unsigned char ucIdx = 0; ucNumOfBlinking >= ucIdx; ++ucIdx) {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(usStartupDelay / (2 * ucNumOfBlinking));
    digitalWrite(LED_BUILTIN, LOW);
    delay(usStartupDelay / (2 * ucNumOfBlinking));
  }

  return;
}

void vBootKeyboardInputAsASCII(const unsigned char _ucKeyInput){
  const int siKeyInputInterval = 20;
  
  digitalWrite(LED_BUILTIN, HIGH);
  BootKeyboard.write(_ucKeyInput);
  digitalWrite(LED_BUILTIN, LOW);
  delay(siKeyInputInterval);

  return;
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  vBootKeyboardStartup();
  vBootKeyboardInputAsASCII('0');
  vBootKeyboardInputAsASCII('1');
  vBootKeyboardInputAsASCII('2');
  vBootKeyboardInputAsASCII('\n');
}

void loop() {
}

その他

Arduino Leonardoに関わらず,キーボード動作はKeyboard.hで提供されるもので動作できるのだが,今回のBIOS画面Windowsが起動していない状態では入力ができない(技術的な背景は理解していないが)ことがキーポイントである.また,今回CJMCU Beetleを用いたが,USBポートに挿入した直後にBIOSキーボード入力操作をさせると動作できなかったため,2秒のウェイトを設けている.

改訂履歴
# 日付 内容
1 2023/12/16 記載内容を刷新およびリンク切れ変更

*1:記事記載当時2018/07/22,1ヶ月くらい毎日抜き差しをしていたらしい

*2:海外での個人輸入が怖い場合はAmazon.co.jpで.私は中国での買い物はデビッドカードを使用しています.Amazon.comなどはふつうにクレジットカード.