Linux ドライバ開発でよく使われる関数 copy_from_user open read write の詳細な説明

Linux ドライバ開発でよく使われる関数 copy_from_user open read write の詳細な説明

Linux ドライバーの共通機能 (copy_from_user open read write)

1.開く

関数定義:
int open( const char * pathname, int flags);
int open( const char * pathname,int flags, mode_t mode);
パラメータの説明:
パス名: ファイル名。絶対パスと相対パスを含めることができます。
フラグ: ファイルを開くモード
モード: ファイル所有者、ファイルのユーザー グループ、およびシステム内の他のユーザーのアクセス権を定義するために使用されます。ファイルの権限は次のとおりです: mode&(~umask)
機能説明:
パス名パラメータは、開くファイル パス文字列を指します。 flags パラメータで使用できるフラグは次のとおりです。

  • O_RDONLY はファイルを読み取り専用モードで開きます。
  • O_WRONLY はファイルを書き込み専用で開きます。
  • O_RDWR はファイルを読み取りおよび書き込み可能モードで開きます。

上記の 3 つのフラグは相互に排他的であり、同時に使用することはできませんが、OR (|) 演算子を使用して次のフラグと組み合わせることができます。

  • O_CREAT 開くファイルが存在しない場合は、ファイルが自動的に作成されます。
  • O_EXCL O_CREAT も設定されている場合、このコマンドはファイルが存在するかどうかを確認します。ファイルが存在しない場合は作成されます。存在しない場合は、ファイルを開く際にエラーが発生します。また、O_CREAT と O_EXCL が同時に設定されており、開くファイルがシンボリックリンクの場合、ファイルのオープンは失敗します。
  • O_NOCTTY 開くファイルが端末デバイスの場合、その端末はプロセス制御端末として使用されません。
  • O_TRUNC ファイルが存在し、書き込みモードで開かれている場合、このフラグはファイルの長さを 0 にクリアし、ファイルに元々保存されていたデータは消えます。
  • O_APPEND ファイルの読み取りまたは書き込み時に、データがファイルの末尾に追加されます。
  • O_NONBLOCK はブロックできない方法でファイルを開きます。つまり、読み取るデータや待機するデータがあるかどうかに関係なく、すぐにプロセスに戻ります。
  • O_NDELAY は O_NONBLOCK と同じです。
  • O_SYNC はファイルを同期的に開きます。
  • O_NOFOLLOW パラメータパス名が指すファイルがシンボリックリンクの場合、ファイルのオープンは失敗します。
  • O_DIRECTORY パラメータ パス名で指定されたファイルがディレクトリでない場合、ファイルのオープンは失敗します。

これは、いくつかのシステム セキュリティの問題を回避するための、Linux 2.2 以降に固有のフラグです。パラメータ mode には以下の組み合わせがあり、新規ファイル作成時にのみ有効となります。また、実際にファイルを作成する際の権限は umask 値の影響を受けるため、ファイル権限は (mode-umaks) とする必要があります。

  • S_IRWXU00700 権限。これは、ファイル所有者が読み取り、書き込み、および実行権限を持っていることを意味します。
  • S_IRUSR または S_IREAD、00400 権限。これは、ファイル所有者が読み取り権限を持っていることを意味します。
  • **S_IWUSR または S_IWRITE、00200 ** 権限、ファイル所有者に書き込み権限があることを示します。
  • S_IXUSR または S_IEXEC、00100 権限。これは、ファイル所有者が実行権限を持っていることを意味します。
  • S_IRWXG 00070 権限。これは、ファイル ユーザー グループに読み取り、書き込み、および実行権限があることを意味します。
  • S_IRGRP 00040 権限。ファイル ユーザー グループに読み取り権限があることを示します。
  • S_IWGRP 00020 権限。ファイル ユーザー グループに書き込み権限があることを示します。
  • S_IXGRP 00010 権限。ファイル ユーザー グループに実行権限があることを示します。
  • S_IRWXO 00007 権限。これは、他のユーザーに読み取り、書き込み、実行権限があることを意味します。
  • S_IROTH 00004 権限。他のユーザーには読み取り権限があることを示します。
  • S_IWOTH 00002 権限。他のユーザーに書き込み権限があることを示します。
  • S_IXOTH 00001 権限。他のユーザーには実行権限があることを示します。

戻り値:
チェックするすべての権限がチェックに合格すると、成功を示す 0 の値が返されます。いずれかの権限が拒否された場合は、-1 が返されます。

エラーコード:
EEXIST パラメータ パス名で参照されるファイルは既に存在しますが、O_CREAT および O_EXCL フラグが使用されています。
EACCESS パラメータ パス名が指すファイルは、テストに必要な権限を満たしていません。
EROFS 書き込み権限をテストするファイルは読み取り専用ファイル システムに存在します。
EFAULT パラメータ パス名ポインタがアクセス可能なメモリ領域を超えています。
EINVAL パラメータ モードが正しくありません。
ENAMETOOLONG パラメータのパス名が長すぎます。
ENOTDIR パラメータ パス名はディレクトリではありません。
ENOMEM カーネルメモリが不足しています。
ELOOP パラメータ パス名にシンボリック リンクが多すぎます。
EIO I/O アクセス エラー。

#含む
#含む
#含む
#含む
主要()
{
    int fd、サイズ;
    char s[]=”Linuxプログラマー!\n”,buffer[80];
    fd = open("/tmp/temp", O_WRONLY | O_CREAT);
    書き込み(fd,s,sizeof(s));
    閉じる(fd);
    fd = open ("/tmp/temp", O_RDONLY);
    サイズ=読み取り(fd、バッファ、バッファのサイズ)。
    閉じる(fd);
    printf("%s",バッファ);
}

2.読む

関数定義:
ssize_t read(int fd, void * buf, size_t count);

機能の説明:
read() は、パラメータ fd が指すファイルから buf ポインタが指すメモリに count バイトを転送します。

戻り値:
戻り値は実際に読み取られたバイト数です。0 が返された場合は、ファイルの末尾に到達したか、読み取るデータがもうないことを意味します。 count パラメータが 0 の場合、read() は効果がなく、0 を返します。

知らせ:
読み取り時に fd 内のデータが読み取るデータより小さい場合、ブロックが発生します。
read の使い方は write よりも簡単なので、ここでは詳細には説明しません。著者のレベルが限られているため、記事に誤りがある場合は、皆様に誤解を与えないようご指摘いただければ幸いです。

3.書く

関数定義:
ssize_t write (int fd, const void * buf, size_t count);

機能の説明:
write() は、パラメータ buf が指すメモリから count バイトをパラメータが指すファイルに書き込みます。

戻り値:
すべてがうまくいけば、write() は実際に書き込まれたバイト数を返します。エラーが発生した場合は -1 が返され、エラー コードが errno に格納されます。
(1) write() 関数の戻り値は通常 0 ではありません。write(fp, p1+len, (strlen(p1)-len) の 3 番目のパラメータが 0 である場合にのみ 0 を返します。この場合、write() は何も行わず、0 のみを返します。man マニュアルに記載されている write() の戻り値の説明は次のとおりです。
(2) write()関数がbufからfdにデータを書き込むとき、bufのデータを一度にすべて読み取れない場合、bufのデータを2回目に読み取るときに、その読み取り位置ポインタ(つまり、2番目のパラメータbuf)は自動的に移動しません。プログラマは、bufの最初のアドレスを2番目のパラメータに単に入力するのではなく、プログラムで制御する必要があります。たとえば、読み取り位置は、write(fp, p1+len, (strlen(p1)-len) という形式で移動できます。このように、2 番目の書き込みループでは、p1+len から fp にデータが書き込まれ、(strlen(p1)-len) が 0 になるまで、残りの部分でも同じ処理が行われます。

次の例は、書き込み関数の使用方法を示しています。

#含む 
#含む 
#含む 
int メイン()
{
  char *p1 = "これはACテストコードです";
  揮発性int len ​​= 0;
 
  int fp = open("/home/test.txt", O_RDWR|O_CREAT);
  のために(;;)
  {
     整数n;
 
     if((n=write(fp, p1+len, (strlen(p1)-len)))== 0) //if((n=write(fp, p1+len, 3)) == 0) 
     { //strlen(p1) = 21
         printf("n = %d \n", n);
         壊す;
     }
     長さ+=n;
  }
  0を返します。
}

(3)一度に書き込むことができる最大データ範囲(BUFSIZ、8192と思われる)内では、エラーを回避するために、3番目のパラメータcountはbuf内のデータのサイズにするのが望ましい。 (再度テストしてみたところ、一度に書き込めるデータの最大数は 8192 ではないことがわかりました。81920000 を一度に書き込んでみましたが、結果も OK でした。一度に書き込めるデータの最大数は 8192 ではないようです。ただし、カーネル内には確かに BUFSIZ というパラメータがあり、その具体的な意味は未だ調査中です。)

4.ユーザーにコピー

関数定義:
unsigned long copy_to_user(void *to, const void *from, unsigned long n)
パラメータの説明:
to: ターゲットアドレス(ユーザー空間)
from: 送信元アドレス (カーネル空間)
n: コピーするデータのバイト数
機能の説明:
カーネル空間からユーザー空間にデータを読み取る
戻り値:
成功した場合は 0 を返し、失敗した場合は正常にコピーされなかったデータのバイト数を返します。

5.ユーザーからコピー

関数定義:
unsigned long copy_from_user(void *to, const void *from, unsigned long n);
パラメータの説明:
to: ターゲットアドレス(カーネル空間)
from: 送信元アドレス (ユーザー空間)
n: コピーするデータのバイト数
機能説明:
ユーザー空間からカーネル空間にデータを読み取る
戻り値:
成功した場合は 0 を返し、失敗した場合は正常にコピーされなかったデータのバイト数を返します。

上記は、Linux ドライバーのよく使われる機能 (copy_from_user open read write) の詳細です。Linux ドライバーのよく使われる機能の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。今後とも123WORDPRESS.COMをよろしくお願いいたします!

以下もご興味があるかもしれません:
  • Linuxサービスの監視と運用および保守
  • Linux スクリプトの基礎を詳しく紹介
  • Linux カーネルプログラミングにおけるコンテナの of() 関数の紹介
  • VS2019 で Linux C++ プログラムを開発するための実装手順
  • Linux 上級学習マニュアル (パート 2)
  • Linux 上級学習マニュアル (パート 1)
  • 学習マニュアル - Linux の基礎

<<:  MYSQL データベースの基礎 - 結合操作の原理

>>:  ボックスモデルのサイズの詳細な説明は、パディング、マージン、境界の値によって異なります。

推薦する

CSS ハック \9 と \0 は IE11\IE9\IE8 のハッキングには機能しない可能性があります

Web ページやフォームを設計するたびに、さまざまなブラウザ、特に IE ファミリの互換性の問題に悩...

React 入門レベルの詳細なメモ

目次1. Reactの基本的な理解1. はじめに2. Reactの特徴3. Reactが効率的な理由...

Navicat for SQLite で中国語データを CSV にインポートする方法

この記事では、参考までに、csv中国語データをNavicat for SQLiteにインポートする具...

MySQL アクティブ-アクティブ同期レプリケーションの 4 つのソリューションの詳細な説明

目次MySQLネイティブレプリケーションに基づくマスター-マスター同期ソリューションGaleraレプ...

JavaScriptのループの違いについての詳細な説明

目次序文列挙可能なプロパティ反復可能なオブジェクトforEachメソッドとmapメソッドチェーン呼び...

Mysqlの日付と時刻関数を扱う記事

目次序文1. 現在の時刻を取得する1.1 現在の日付と時刻を返す1.2 現在の日付を取得する1.3 ...

TypeScript ジェネリックパラメータのデフォルト型と新しい厳密なコンパイルオプション

目次概要コンポーネントクラスの型定義を作成するジェネリック型を使用してPropsとStateを定義す...

jQueryは居住地を選択するためのドロップダウンボックスを実装します

居住地を選択するためのドロップダウンボックスをjQueryで実装するための具体的なコードは参考までに...

...

URL 内の特殊記号の意味を知っていますか?

1.# # は Web ページ内の場所を表します。右側の文字はその位置の識別子です。たとえば、ht...

MySQL InnoDB ロックの概要

目次1. 共有ロックと排他ロック2. 意図ロック3. レコードロック4. ギャップロック5. ネクス...

Mysql接続数の設定と取得方法

接続数を取得する --- 最大接続数を取得します。SHOW VARIABLES LIKE '...

Vueでaxiosをカプセル化するいくつかの方法

目次ベーシックエディションステップ1: Axiosを構成するステップ2: リクエストをカプセル化する...

ファイアウォールの iptables 戦略を使用して Linux サーバー上のポートを転送する方法

2つの異なるサーバー間の転送ポート転送を有効にするまず、デフォルトでは無効になっている IP 転送機...

nginx共有メモリの仕組みの詳細な説明

Nginx の共有メモリは、高いパフォーマンスを実現できる主な理由の 1 つであり、主にファイル キ...