web-dev-qa-db-ja.com

カーネルプログラミングの学習

Linuxカーネルプログラミングを学びたいです。

そのための出発点は何でしょうか?対象とするより単純な問題のいくつかは何でしょうか?

47
Geek

Linuxカーネルプログラミングに関するRobertLoveの本を手に入れてみてください。その非常に簡潔でわかりやすいです。

その後またはそれに伴い、「Linuxカーネルについて」をご覧になることをお勧めしますが、初期段階ではお勧めしません。

また、 Linuxカーネルプログラミングガイド もご覧ください。カーネルモジュールのプログラミングから多くのことを学ぶことができるので、そのガイドが役に立ちます。はい、多くの情報については、カーネルソースtarballの「documentation」サブディレクトリを参照してください。

28
user59634
**TODO** +editPic: Linux Kernel Developer -> (Ring Layer 0)
         +addSection: Kernel Virtualization Engine

KERN_WARN_CODING_STYLE: Do not Loop unless you absolutely have to.

初期化されていないvoid *iの推奨書籍

「男性は、ある程度の生命が得られるまで本を理解しないか、いずれにせよ、その内容の少なくとも一部を見て生きるまで、深い本を理解する人はいない」。 –エズラパウンド

1000コードマイルの旅は、1つのステップから開始する必要があります。次の本のどれから始めるかについて混乱している場合でも、心配しないで、お好きな本を選んでください。さまよう者全員が失われるわけではありません。 すべての道路が最終的に高速道路に接続するため、行き止まりに遭遇することなくページが進むにつれて、カーネルジャーニーで新しいことを探索し、最終的にcode-setに接続します。注意深く読んで覚えておいてください:コードは文学ではありません

残っているのは、物でも、感情でも、イメージでも、精神的な絵でも、記憶でも、アイデアでもありません。機能です。ある種のプロセス。 「より大きな」何かの関数として説明できる人生の側面。したがって、それは実際には他の何かから「分離」されていないように見えます。ナイフの機能のように-何かを切る-実際には、ナイフ自体から分離されていません。この機能は現在使用されている場合と使用されていない場合がありますが、分離されることはありません。

素数性テストのためのソロベイ-シュトラッセン非ランダム化アルゴリズム

Solovay Strassen Derandomized Algorithm for Primality Test

矛盾したり混乱したりしないように読んでください。また、信じて当然のことと考えることもありません。また、話や談話を見つけることもありません。しかし、計量して検討する必要があります。味わう本もあれば、飲み込む本もあれば、噛んで消化する本もあります。つまり、一部の本だけを読む、他の本は読むが不思議ではない、いくつかの本は完全に読む必要があります。 、そして勤勉と注意を払って。

static void tasklet_hi_action(struct softirq_action *a)
{
        struct tasklet_struct *list;

        local_irq_disable();
        list = __this_cpu_read(tasklet_hi_vec.head);
        __this_cpu_write(tasklet_hi_vec.head, NULL);
        __this_cpu_write(tasklet_hi_vec.tail, this_cpu_ptr(&tasklet_hi_vec.head));
        local_irq_enable();

        while (list) {
                struct tasklet_struct *t = list;

                list = list->next;

                if (tasklet_trylock(t)) {
                        if (!atomic_read(&t->count)) {
                                if (!test_and_clear_bit(TASKLET_STATE_SCHED,
                                                        &t->state))
                                        BUG();
                                t->func(t->data);
                                tasklet_unlock(t);
                                continue;
                        }
                        tasklet_unlock(t);
                }

                local_irq_disable();
                t->next = NULL;
                *__this_cpu_read(tasklet_hi_vec.tail) = t;
                __this_cpu_write(tasklet_hi_vec.tail, &(t->next));
                __raise_softirq_irqoff(HI_SOFTIRQ);
                local_irq_enable();
        }
}

コアLinux(5-> 1-> 3-> 2-> 7-> 4-> 6)

「自然にはカーネルもシェルもありません。彼女は一度にすべてです」-ヨハン・ヴォルフガング・フォン・ゲーテ

読者は オペレーティングシステムの概念 に精通している必要があります。実行時間の長いプロセスと、実行のバーストが短いプロセスとの違いについての公正な理解。ソフトおよびハードのリアルタイム制約を満たしながら、フォールトトレランス。読んでいる間、コアサブシステムのLinuxカーネルソースによって行われた設計上の選択を理解し、n/ackすることが重要です。

スレッド[および]シグナルは、プラットフォームに依存する悲惨、絶望、恐怖、狂気の痕跡です(〜AnthonyBaxte)。そうは言っても、カーネルに飛び込む前に、自己評価型のCエキスパートになる必要があります。また、リンクリスト、スタック、キュー、レッドブラックツリー、ハッシュ関数などについても十分な経験が必要です。

volatile int i;
int main(void)
{
    int c;
    for (i=0; i<3; i++) {
        c = i&&&i;
        printf("%d\n", c);    /* find c */
    }
    return 0;
}

Linuxカーネルソースの美しさと芸術は、一緒に使用される意図的なコードの難読化にあります。これは、2つ以上の操作を含む計算上の意味をクリーンでエレガントな方法で伝えるために必要になることがよくあります。これは、マルチコアアーキテクチャのコードを作成する場合に特に当てはまります。

リアルタイムシステムでのビデオレクチャータスクスケジューリングメモリ圧縮メモリバリア[〜#〜] smp [〜#〜]

#ifdef __compiler_offsetof
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
#else
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
  1. Linuxカーネル開発 -Robert Love
  2. Linuxカーネルを理解する -Daniel P. Bovet、Marco Cesati
  3. The Art of Linux KerneL Design -Yang Lixiang
  4. Professional Linux Kernel Architecture -Wolfgang Mauerer
  5. NIXオペレーティングシステムの設計 -Maurice J. Bach
  6. Linux Virtual Memory Managerについて -Mel Gorman
  7. Linuxカーネル内部 -Tigran Aivazian
  8. 埋め込みLinux入門書 -クリストファー・ハリナン

Linuxデバイスドライバー(1-> 2-> 4-> 3-> 8-> ...)

「音楽はあなたを運びません。あなたは感情や物語のその小さな小さな核に本当に集中するあなたの能力によって厳密にそれを運ばなければなりません」。 -デビーハリー

あなたの仕事は基本的にハードウェアデバイスとソフトウェアカーネルの間に高速通信インターフェースを確立することです。ハードウェアリファレンスデータシート/マニュアルを読んで、デバイスの動作とその制御およびデータの状態、および提供されている物理チャネルを理解する必要があります。特定のアーキテクチャのアセンブリに関する知識と、VHDLやVerilogなどのVLSIハードウェア記述言語に関する公正な知識が長期的に役立ちます。

[〜#〜] q [〜#〜]:しかし、なぜハードウェアの仕様を読まなければならないのですか?

[〜#〜] a [〜#〜]:なぜなら、「ソフトウェアが橋渡しできない炭素とシリコンの割れ目がある」からです-Rahul Sonnad

ただし、上記は計算アルゴリズムドライバーコード -下半分)では問題になりません。処理)、 ユニバーサルチューリングマシン で完全にシミュレートできるため。計算結果が 数学領域 で当てはまる場合、それが 物理領域 でも当てはまるのは確実です。

Linuxデバイスドライバーでのビデオレクチャー (Lec。17&18)、 組み込みKMSドライバーの構造ピン制御とGPIOアップデート共通クロックフレームワーク実際のLinuxドライバーを作成する-Greg KH

static irqreturn_t phy_interrupt(int irq, void *phy_dat)
{
         struct phy_device *phydev = phy_dat;

         if (PHY_HALTED == phydev->state)
                 return IRQ_NONE;                /* It can't be ours.  */

         /* The MDIO bus is not allowed to be written in interrupt
          * context, so we need to disable the irq here.  A work
          * queue will write the PHY to disable and clear the
          * interrupt, and then reenable the irq line.
          */
         disable_irq_nosync(irq);
         atomic_inc(&phydev->irq_disable);

         queue_work(system_power_efficient_wq, &phydev->phy_queue);

         return IRQ_HANDLED;
}
  1. Linuxデバイスドライバー -Jonathan Corbet、Alessandro Rubini、およびGreg Kroah-Hartman
  2. 必須のLinuxデバイスドライバー -Sreekrishnan Venkateswaran
  3. Linuxデバイスドライバーの作成 -Jerry Cooperstein
  4. Linuxカーネルモジュールプログラミングガイド -Peter Jay Salzman、Michael Burian、Ori Pomerantz
  5. Linux PCMCIAプログラマーズガイド -David Hinds
  6. Linux SCSIプログラミングハウツー -Heiko Eibfeldt
  7. POSIXオペレーティングシステムのシリアルプログラミングガイド -Michael R.Sweet
  8. Linuxグラフィックスドライバー:はじめに -StéphaneMarchesin
  9. Linux USBデバイスドライバーのプログラミングガイド -Detlef Fliegl
  10. Linuxカーネルデバイスモデル -Patrick Mochel

カーネルネットワーク(1-> 2-> 3-> ...)

「一族と呼び、ネットワークと呼び、部族と呼び、家族と呼びます。何と呼んでも、誰であれ、必要です。」 -ジェーンハワード

カーネル内のパケットウォークスルーを理解することは、カーネルネットワークを理解するための鍵です。 NetfilterやIPSecの内部などを理解したい場合は、それを理解する必要があります。 Linuxカーネルネットワーク層の2つの最も重要な構造は、struct sk_buffstruct net_deviceです。

static inline int sk_hashed(const struct sock *sk)
{
        return !sk_unhashed(sk);
} 
  1. Linuxネットワークの内部を理解する -Christian Benvenuti
  2. Linuxカーネルネットワーキング:実装と理論 -Rami Rosen
  3. NIXネットワークプログラミング -W。リチャードスティーブンス
  4. Linuxネットワークプログラミングの決定的なガイド -Keir Davis、John W. Turner、Nathan Yocom
  5. Linux TCP/IPスタック:組み込みシステムのネットワーキング -トーマスF.ハーバート
  6. 例によるLinuxソケットプログラミング -Warren W.Gay
  7. Linux Advanced Routing&Traffic Control HOWTO -Bert Hubert

カーネルデバッグ(1-> 4-> 9-> ...)

それとのコミュニケーションにおいて、それが何を意味するのかを正確に言わない限り、トラブルは必ず結果として生じます。 〜アランチューリング、コンピューターについて

Brian W. Kernighanは、Unix for Beginners(1979)の論文で、「最も効果的なデバッグツールは、慎重に検討し、慎重に配置された印刷ステートメントと組み合わせることです」と述べています。何を収集するかを知っていると、適切なデータをすばやく取得して迅速に診断するのに役立ちます。偉大なコンピューター科学者のエドガー・ダイクストラはかつて、テストはバグの存在を示すことはできるが、バグがないことを示すことはできないと述べました。優れた調査手法は、問題を迅速に解決する必要性、スキルを構築する必要性、および対象分野の専門家の効果的な使用のバランスを取る必要があります。

底を打ったとき、何も機能していないように見え、すべてのオプションが不足することがあります。その後、実際のデバッグが始まります。バグは、効果のないソリューションへの固定から解放するために必要な休憩を提供する可能性があります。

カーネルデバッグとプロファイリングに関するビデオレクチャーコアダンプ分析マルチコアデバッグGDBを使用マルチコア競合状態の制御電子機器のデバッグ

/* Buggy Code -- Stack frame problem
 * If you require information, do not free memory containing the information
 */
char *initialize() {
  char string[80];
  char* ptr = string;
  return ptr;
}

int main() {
  char *myval = initialize();
  do_something_with(myval);
}
/*  “When debugging, novices insert corrective code; experts remove defective code.”
 *     – Richard Pattis
#if DEBUG
 printk("The above can be considered as Development and Review in Industrial Practises");
#endif
 */
  1. Linuxのデバッグとパフォーマンスの調整 -Steve Best
  2. Linuxアプリケーションのデバッグ手法 -Aurelian Melinte
  3. GDBを使用したデバッグ:GNUソースレベルのデバッガー -Roland H. Pesch
  4. 組み込みLinuxのデバッグ -クリストファー・ハリナン
  5. GDB、DDD、およびEclipseを使用したデバッグの技術 -Norman S. Matloff
  6. プログラムが失敗する理由:体系的なデバッグのガイド -Andreas Zeller
  7. ソフトウェアエクソシズム:レガシーコードのデバッグと最適化のためのハンドブック -ビルブランデン
  8. デバッグ:最もとらえどころのないソフトウェアとハ​​ードウェアの問題を見つける -David J. Agans
  9. 思考によるデバッグ:学際的なアプローチ -Robert Charles Metzger
  10. バグを見つける:間違ったプログラムの本 -Adam Barr

ファイルシステム(1-> 2-> 6-> ...)

「少なくともファイルシステムと結合されているので、仮想メモリが欲しかった」。 -ケン・トンプソン

UNIXシステムでは、すべてがファイルです。何かがファイルでない場合、名前付きパイプとソケットを除いて、それはプロセスです。ファイルシステムでは、ファイルはinodeで表されます。これは、ファイルを構成する実際のデータに関する情報を含むシリアル番号の一種です。 Linux仮想ファイルシステムVFSは、マウントおよび使用時に各ファイルシステムの情報をメモリにキャッシュします。これらのキャッシュ内のデータは、ファイルとディレクトリの作成、書き込み、および削除時に変更されるため、ファイルシステムを正しく更新するには多くの注意が必要です。これらのキャッシュの中で最も重要なのはバッファキャッシュです。これは、個々のファイルシステムが基盤となるブロックストレージデバイスにアクセスする方法に統合されています。

ストレージシステムでのビデオ講義フラッシュフレンドリーファイルシステム

long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
{
        struct open_flags op;
        int fd = build_open_flags(flags, mode, &op);
        struct filename *tmp;

        if (fd)
                return fd;

        tmp = getname(filename);
        if (IS_ERR(tmp))
                return PTR_ERR(tmp);

        fd = get_unused_fd_flags(flags);
        if (fd >= 0) {
                struct file *f = do_filp_open(dfd, tmp, &op);
                if (IS_ERR(f)) {
                        put_unused_fd(fd);
                        fd = PTR_ERR(f);
                } else {
                        fsnotify_open(f);
                        fd_install(fd, f);
                }
        }
        putname(tmp);
        return fd;
}

SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
{
        if (force_o_largefile())
                flags |= O_LARGEFILE;

        return do_sys_open(AT_FDCWD, filename, flags, mode);
}
  1. Linuxファイルシステム -Moshe Bar
  2. Linuxファイルシステム -William Von Hagen
  3. NIXファイルシステム:進化、設計、および実装 -スティーブD.ペイト
  4. 実用的なファイルシステム設計 -ドミニクジャンパオロ
  5. ファイルシステムフォレンジック分析 -ブライアンキャリア
  6. Linuxファイルシステム階層 -Binh Nguyen
  7. BTRFS:Linux Bツリーファイルシステム -Ohad Rodeh
  8. StegFS:Linux用のステガノグラフィファイルシステム -Andrew D. McDonald、Markus G. Kuhn

セキュリティ(1-> 2-> 8-> 4-> 3-> ...)

「UNIXは、ユーザーが愚かなことをするのを阻止するようには設計されていません。それは、ユーザーが賢いことをするのも阻止するからです」。 —ダグ・グウィン

使用しないとテクニックは機能しません。倫理はテクノロジーによって変化します。

"F×S = k"自由と安全の積は定数です。 -ニヴェンの法則

暗号化は、オンラインでの信頼の基盤を形成します。ハッキングとは、技術的、物理的、または人間ベースの要素でセキュリティ制御を悪用することです。実行中の他のプログラムからカーネルを保護することは、安全で安定したシステムへの第一歩ですが、これは明らかに十分ではありません。異なるユーザーランドアプリケーション間でもある程度の保護が存在する必要があります。エクスプロイトは、ローカルサービスまたはリモートサービスを標的にすることができます。

「運命をハックすることはできません。ブルートフォース...バックドア、ライフへのサイドチャネルが必要です。」― Clyde Dsouza

コンピュータは問題を解決するのではなく、解決策を実行します。すべての 非決定論的 アルゴリズムコードの背後には、 決定的 マインドがあります。 -/ var/log/dmesg

暗号化とネットワークセキュリティに関するビデオレクチャーセキュリティのための名前空間保護リモート攻撃Secure Embedded Linux

env x='() { :;}; echo vulnerable' bash -c "echo this is a test for Shellsock"
  1. ハッキング:搾取の芸術 -ジョンエリクソン
  2. ルートキットアーセナル:システムのダークコーナーでの脱出と回避 -ビルブランデン
  3. 公開されたハッキン​​グ:ネットワークセキュリティの秘密 -Stuart McClure、Joel Scambray、George Kurtz
  4. カーネル活用ガイド:コアへの攻撃 -Enrico Perla、Massimiliano Oldani
  5. The Art of Memory Forensics -Michael Hale Ligh、Andrew Case、Jamie Levy、AAron Walters
  6. 実用的なリバースエンジニアリング -ブルース・ダング、アレクサンドル・ガゼット、エリアス・バシャラニー
  7. 実用的なマルウェア分析 -Michael Sikorski、Andrew Honig
  8. 最大のLinuxセキュリティ:Linuxサーバーを保護するためのハッカーガイド -匿名
  9. Linuxセキュリティ -Craig Hunt
  10. 実世界のLinuxセキュリティ -ボブトクセン

カーネルソース(0.11-> 2.4-> 2.6-> 3.18)

「ワインのように、カーネルプログラミングの習得は時間とともに成熟します。しかし、ワインとは異なり、その過程で甘くなります」。 -ローレンス・ムチェカ

プログラマーがアーティストだとは思わないかもしれませんが、プログラミングは非常にクリエイティブな職業です。それは論理ベースの創造性です。コンピュータサイエンスの教育は、ブラシと顔料を研究することで誰かを専門の画家にすることができる以上に、誰もが専門のプログラマーになることはできません。すでにご存知のように、道を知ることと道を歩くことには違いがあります。カーネルソースコードで袖をまくり上げて手を汚すことが最も重要です。最後に、こうして得られたカーネル知識を使用すると、どこに行っても輝きします。

未熟なコーダーは模倣します。成熟したコーダーは盗みます。悪いコーダーは彼らが取るものを汚し、良いコーダーはそれをより良いもの、または少なくとも何か違うものに変えます。優れたコーダーは、盗難を、それが引き裂かれたときとはまったく異なる独特の感覚全体に溶け込ませます。

カーネルレシピに関するビデオ講義

linux-0.11
├── boot
│   ├── bootsect.s      head.s      setup.s
├── fs
│   ├── bitmap.c    block_dev.c buffer.c        char_dev.c  exec.c
│   ├── fcntl.c     file_dev.c  file_table.c    inode.c     ioctl.c
│   ├── namei.c     open.c      pipe.c          read_write.c
│   ├── stat.c      super.c     truncate.c
├── include
│   ├── a.out.h     const.h     ctype.h     errno.h     fcntl.h
│   ├── signal.h    stdarg.h    stddef.h    string.h    termios.h
│   ├── time.h      unistd.h    utime.h
│   ├── asm
│   │   ├── io.h    memory.h    segment.h   system.h
│   ├── linux
│   │   ├── config.h    fdreg.h fs.h    hdreg.h     head.h
│   │   ├── kernel.h    mm.h    sched.h sys.h       tty.h
│   ├── sys
│   │   ├── stat.h      times.h types.h utsname.h   wait.h
├── init
│   └── main.c
├── kernel
│   ├── asm.s       exit.c      fork.c      mktime.c    panic.c
│   ├── printk.c    sched.c     signal.c    sys.c       system_calls.s
│   ├── traps.c     vsprintf.c
│   ├── blk_drv
│   │   ├── blk.h   floppy.c    hd.c    ll_rw_blk.c     ramdisk.c
│   ├── chr_drv
│   │   ├── console.c   keyboard.S  rs_io.s
│   │   ├── serial.c    tty_io.c    tty_ioctl.c
│   ├── math
│   │   ├── math_emulate.c
├── lib
│   ├── close.c  ctype.c  dup.c     errno.c  execve.c  _exit.c
│   ├── malloc.c open.c   setsid.c  string.c wait.c    write.c
├── Makefile
├── mm
│   ├── memory.c page.s
└── tools
    └── build.c
  1. 初心者は Linux 0.11ソース (20,000行未満のソースコード)から始めます。 Linux 0.11と比較して20年の開発の後、Linuxは非常に巨大で複雑になり、習得が困難になりました。しかし、デザインコンセプトと主要な構造に根本的な変更はありません。 Linux 0.11を学ぶことは、依然として重要な実践的意義を持っています。
  2. カーネルハッカーの必読=> Linux_source_dir/Documentation/*
  3. 少なくとも1つのカーネルメーリングリストに登録してアクティブにする必要があります。 カーネル初心者 で始まります。
  4. 完全なソースコードを読む必要はありません。カーネルAPIとその使用法に慣れたら、関心のあるサブシステムのソースコードから直接始めます。また、独自のプラグアンドプレイモジュールを作成してカーネルを試すこともできます。
  5. デバイスドライバーの作成者は、専用のハードウェアを用意することでメリットが得られます。 Raspberry Pi で始まります。
62
manav m-n

チェックアウト Linuxカーネル管理人プロジェクト

「Linuxカーネルのソースコードを調べ、コードレビューを行い、メンテナンスされていないコードを修正し、その他のクリーンアップとAPI変換を行います。カーネルハッキングの良いスタートです」

8
John Smith

私は言わなければならないでしょう:「Cを学ぶ」。 :)

この無料のオンラインブックをお試しください。

Linuxカーネルモジュールプログラミングガイドhttp://www.linuxhq.com/guides/LKMPG/mpg.html

5
Antonio Louro
5
Raulp

いくつかのリソース:

  • 本:Robert Love、Linuxカーネル開発、第3版
  • ブック:Corbet、Rubini、Linuxデバイスドライバー、第3版(無料バージョン ここ
  • 本:一言で言えばLinuxカーネル(無料版 ここ
  • 自由電子 によって提供される自由材料
1
Claudio

Kernelnewbies.orgを確認し、Kernelnewbiesメーリングリストに登録して、irc.oftc.org#kernelnewbiesにアクセスしてください。

1
chill