C LANGUAGE TECHNOLOGY

【C言語】Raspberry Pi 3のユーザモードとカーネルモードでプログラムの実行

悩んでいる人

C言語でRaspberry Pi 3のユーザモードとカーネルモードでプログラムの実行方法を教えて!

こういった悩みにお答えします.

本記事の信頼性

  • リアルタイムシステムの研究歴12年.
  • 東大教員の時に,英語でOSの授業.
  • 2012年9月~2013年8月にアメリカのノースカロライナ大学チャペルヒル校コンピュータサイエンス学部2021年の世界大学学術ランキングで20位)で客員研究員として勤務.C言語でリアルタイムLinuxの研究開発
  • プログラミング歴15年以上,習得している言語: C/C++,Java,Python,Ruby,HTML/CSS/JS/PHP,MATLAB,Assembler (x64,ARM).
  • 東大教員の時に,C++言語で開発した「LLVMコンパイラの拡張」,C言語で開発した独自のリアルタイムOS「Mcube Kernel」GitHubにオープンソースとして公開

こういった私から学べます.

Raspberry Pi 3

Raspberry Pi 3(ラズパイ3)とは,イギリスのラズベリーパイ財団により開発されているARMプロセッサを搭載したシングルボードコンピュータです.

Raspberry Piシリーズは2021年1月21日時点で累計3,700万台以上売れていて,世界中で使われています.

Raspberry PiはIoT・組込みボードのデファクトスタンダード(事実上の標準)と言えるでしょう.

2021年現在の最新版はRaspberry Pi 4(ラズパイ4)ですが,本記事ではエミュレータ等の開発環境が整っているRaspberry Pi 3を紹介します.

Raspberry Pi 3のエミュレータ「QEMU」

Raspberry Pi 3の代表的なエミュレータは,QEMU(キューエム)です.

QEMUを利用すると,Raspberry Pi 3の実機を使わないでコードを書いて実行できます.

つまり,Raspberry Pi 3の実機でプログラムを実行する毎に転送したり,電源をON/OFFしたりする手間を減らせます.

電源のON/OFFを頻繁にするとRaspberry Pi 3の実機が壊れる可能性があるので,実機で実行する必要がある時以外はQEMUで開発することをおすすめします.

QEMUはRaspberry Pi 3のユーザモードとカーネルモードの両方をサポートしています.

Ubuntu 20.04LTSでQEMUをインストールするためには,以下のコマンドを実行します.

インストールされるQEMUバージョンは4.2.1です.

※QEMUのバージョン2.12.0以降でRaspberry Pi 3をサポートしています.

Raspberry Pi 3でC言語のプログラミング

それでは,Raspberry Pi 3でC言語のプログラミングをしましょう.

具体的には,"Hello World"を表示します.

"Hello World"を表示するコードは以下になります.

Intel 64ビットCPUのユーザモードで実行

Intel 64ビットCPU(ホストマシン)のユーザモードで実行します.

当たり前ですが,正常に動作しました.

ARM 64ビットCPUのクロスコンパイラ「aarch64-linux-gnu-gcc」のインストール

ARM64ビットCPUのクロスコンパイラ「aarch64-linux-gnu-gcc」をインストールします.

以下のコマンドを実行します.

ARM 64ビットCPUのユーザモードで実行

ARM 64ビットCPUのユーザモードで実行します.

Raspberry Pi 3のボード依存ではなく,ARM 64ビットCPUなら何でも実行できます.

静的リンクと動的リンクの両方の方法を解説していきます.

静的リンクで実行

静的リンクで実行するためには,コンパイル時に-staticオプションを入れます.

※-staticオプションはライブラリを静的リンクするという意味です.

qemu-user-staticをインストールした時にbinfmtの設定を行うので,ARM 64ビット(aarch64)のELFオブジェクトを実行する時に自動的にARM 64ビットのユーザモードのエミュレータqemu-aarch64-staticを経由して実行します.

つまり,以下のようにqemu-aarch64-staticコマンドを明示的に実行する場合と同じです.

動的リンクで実行

動的リンク(-staticオプションなし)で実行すると,正常に動作しません.

動的リンクのライブラリファイル/lib/ld-linux-aarch64.so.1がないというエラーが発生しています.

この理由は,/lib/以下はIntel 64ビットCPU(ホストマシン)の動的リンクのライブラリファイルがあるためです.

※Intel 64ビットCPU用の動的リンクのライブラリファイル/lib/ld-linux.so.2はあります.

/lib/ld-linux-aarch64.so.1は/usr/aarch64-linux-gnu/以下にあるので,ARM 64ビットCPU用の動的リンクのライブラリファイルを見つけるためには,環境変数QEMU_LD_PREFIXに「/usr/aarch64-linux-gnu/」を設定してから実行します.

以下のように設定すると正常に動作しました.

こちらもqemu-aarch64コマンドを明示的に実行する場合と同じです.

ARM 64ビットCPUのカーネルモード(Raspberry Pi 3のベアメタル)で実行

ARM 64ビットCPUのカーネルモード(Raspberry Pi 3のベアメタル)で実行します.

UARTで"Hello World"を出力するコード一式raspberry-pi-3.zipをダウンロードして下さい.

raspberry-pi-3.zipの中身は以下になります.

  • Makefile:ビルド用のMakefile
  • aarch64-elf.ld:ARM 64ビットCPU用のリンカスクリプト
  • include/:ヘッダファイル一式
  • src/:コードファイル一式

複雑なのでコードの解説は省略します.

以下のコマンドで解凍してARM 64ビットCPUのカーネルモードのプログラムをQEMUで実行します.

QEMUを終了するためには,Ctrl + a,xを入力します.

他のQEMUのショートカットはQEMU Tipsを参照して下さい.

Raspberry Pi 3でC言語を学習できるGitHubリポジトリ

Raspberry Pi 3でC言語を学習できるGitHubリポジトリは以下になります.

ベアメタルプログラミングやOS開発という中級者~上級者向けの内容です.

Raspberry Pi 3の実機でプログラミングする時は,必要なパーツの購入し忘れを防ぐためにセットで購入することをおすすめします.


まとめ

Raspberry Pi 3でC言語をプログラミングする方法を紹介しました.

具体的には,Raspberry Pi 3に対応しているエミュレータのQEMUで,ユーザモードとカーネルモードの両方で"Hello World"を出力するプログラムを実行しました.

QEMUを利用するとお手軽にRaspberry Pi 3用のコードが書けて便利ですので,使いこなしましょう.

Raspberry Pi 4用のコードは,QEMUがサポートしたら紹介します.

C言語を独学で習得することは難しいです.

私にC言語の無料相談をしたいあなたは,公式LINE「ChishiroのC言語」の友だち追加をお願い致します.

友だち追加

独学が難しいあなたは,C言語を学べるおすすめのオンラインプログラミングスクール3社で自分に合うスクールを見つけましょう.

-C LANGUAGE, TECHNOLOGY
-, , , , , , , , ,