最初のLinuxデバイスドライバーの作成方法。 パート3

こんばんは。



以前の記事( 1、2、 )では、キャラクターデバイスの概念を定義し、キャラクタードライバーの簡単な例を作成しました。 最後の部分は、パフォーマンスの確認に専念します。 Habrには、ドライバーをテストする方法の例が既にあります(例: tyk)



この問題をより詳細に検討してみます。楽しんでいただければ幸いです。







追加/修正できる考えがある場合は、PMでコメントや手紙をお待ちしています。ありがとうございます。



カーネルモジュールアセンブリ



モジュールをビルドするには、小さなMakefileを作成する必要があります。 Makefileの内容は、 onetwothreeです。 また、学生用のMakefileの例を書いたことがありますが、こちらをクリックしてください



つまり、Makefileはmakeプログラムの一連の指示であり、makeはファイルをある形式から別の形式に変換するプロセスを自動化するユーティリティです。 Makefileの簡単な紹介の後、コードを見ることができます。



メイクファイル:



obj-m += fake.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
      
      





コマンドを見てみましょう:



 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
      
      





ディレクトリを変更することから始まります(私の場合:/lib/modules/4.4.0-93-generic/build)。このディレクトリには、makeユーティリティが読み込むMakefileとカーネルソースが含まれています。 M変数を使用すると、プロジェクトの場所を指定し、指定されたパスに沿って戻ることができます。 つまり、実際には、別のMakefileを使用してモジュールをビルドします。



コマンドラインにmakeを記述し、出力を取得します。



 make -C /lib/modules/4.4.0-93-generic/build M=/home/alexey/Desktop/drivers/character modules make[1]: Entering directory '/usr/src/linux-headers-4.4.0-93-generic' CC [M] /home/alexey/Desktop/drivers/character/fake.o Building modules, stage 2. MODPOST 1 modules CC /home/alexey/Desktop/drivers/character/fake.mod.o LD [M] /home/alexey/Desktop/drivers/character/fake.ko make[1]: Leaving directory '/usr/src/linux-headers-4.4.0-93-generic'
      
      





アセンブリ後、出力はコンパイルされたモジュールfake.koでした。 insmodコマンドでロードします。



次に、次の一連のアクションを実行する必要があります。



  1. モジュールをカーネルにロードします

    実行: sudo insmod fake.ko



  2. dmesgコマンドを使用して、モジュールの予想される出力を確認します

    例: scull: register device major = 243 minor = 0



  3. ファイルシステムにデバイスのファイルを作成します

    例: sudo mknod /dev/scull c 243 0



  4. アクセス権を変更する

    例: sudo chmod 777 /dev/scull





小規模の場合はそのままで、単純にデータの読み取り/書き込みを行う小さなプログラムを作成します。



 #include <fcntl.h> #include <stdio.h> #include <unistd.h> #define DEVICE "/dev/scull" #define BUFF_SIZE 100 int main() { int fd; char ch, write_buf[BUFF_SIZE], read_buf[BUFF_SIZE]; fd = open(DEVICE, O_RDWR); if (!fd) return -1; printf("r - read, w - write\n"); scanf("%c", &ch); switch (ch) { case 'w': printf("enter data: "); scanf(" %[^\n]", write_buf); write(fd, write_buf, sizeof(write_buf)); break; case 'r': read(fd, read_buf, sizeof(read_buf)); printf("scull: %s\n", read_buf); break; } return 0; }
      
      





ヘルスチェック:



  1. コンパイル: gcc test.c -o test



  2. 実行可能ファイルを呼び出します:./test
  3. デバイスに書き込みます: Hello world!



  4. 実行可能ファイルを思い出してください:./test
  5. データの読み取り: scull: Hello world!





これで、単純なシンボリックドライバーのテストが完了しました。新しい機能を考え出し、テストを実装して実行できます。



前回の記事の終わりに、私は調査を実施しました。参加したすべての人に感謝します! すぐに、あるバージョンのカーネルから別のバージョンにデバイスドライバーを移植するプロセスについて書き始めます。



PS記事に誤りがある場合は、メッセージをお待ちしています。ありがとうございます!



All Articles