53

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

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

4

7 に答える 7

76
**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

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

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

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

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

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

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

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();
        }
}

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

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

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

スレッド[および]シグナルは、プラットフォームに依存する悲惨、絶望、恐怖、狂気の軌跡です(〜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カーネル開発-RobertLove
  2. Linuxカーネルを理解する-DanielP.Bovet 、Marco Cesati
  3. LinuxKerneLデザインのアート-YangLixiang
  4. プロフェッショナルLinuxカーネルアーキテクチャ-WolfgangMauerer
  5. UNIXオペレーティングシステムの設計-MauriceJ.Bach
  6. Linux VirtualMemoryManagerを理解する-MelGorman
  7. Linuxカーネルの内部-TigranAivazian
  8. 組み込みLinux入門書-クリストファーハリナン

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

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

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

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

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

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

Linuxデバイスドライバーに関するビデオレクチャー(レクチャー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デバイスドライバー-JonathanCorbet、Alessandro Rubini、Greg Kroah- Hartman
  2. エッセンシャルLinuxデバイスドライバー-SreekrishnanVenkateswaran
  3. Linuxデバイスドライバーの作成-JerryCooperstein
  4. Linuxカーネルモジュールプログラミングガイド-PeterJaySalzman 、Michael Burian、Ori Pomerantz
  5. LinuxPCMCIAプログラマーガイド-DavidHinds
  6. LinuxSCSIプログラミングハウツー-HeikoEibfeldt
  7. POSIXオペレーティングシステムのシリアルプログラミングガイド-MichaelR.Sweet
  8. Linuxグラフィックスドライバー:はじめ-StéphaneMarchesin
  9. LinuxUSBデバイスドライバーのプログラミングガイド-DetlefFliegl
  10. Linuxカーネルデバイスモデル-PatrickMochel

カーネルネットワーク(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ネットワークの内部を理解する-ChristianBenvenuti
  2. Linuxカーネルネットワーキング:実装と理論-Rami Rosen
  3. UNIXネットワークプログラミング-W .リチャードスティーブンス
  4. Linuxネットワークプログラミングの決定的なガイド-KeirDavis 、John W. Turner、Nathan Yocom
  5. Linux TCP / IPスタック:組み込みシステムのネットワーキング-Thomas F. Herbert
  6. 例によるLinuxソケットプログラミング-WarrenW.Gay
  7. Linux Advanced Routing&Traffic Control HOWTO-ベルト・ヒューバート

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

それとコミュニケーションをとる際に、自分が何を意味するのかを正確に言わない限り、問題は必ず発生します。〜Alan Turing、コンピューターについて

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のデバッグとパフォーマンスの調整-SteveBest
  2. Linuxアプリケーションのデバッグ手法-AurelianMelinte
  3. GDBを使用したデバッグ:GNUソースレベルのデバッガー-Roland H. Pesch
  4. 組み込みLinuxのデバッグ-ChristopherHallinan
  5. GDB、DDD、およびEclipseを使用したデバッグの技術-Norman S. Matloff
  6. プログラムが失敗する理由:体系的なデバッグのガイド-Andreas Zeller
  7. Software Exorcism:レガシーコードをデバッグおよび最適化するためのハンドブック-Bill Blunden
  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ファイルシステム-MosheBar
  2. Linuxファイルシステム-WilliamVonHagen
  3. UNIXファイルシステム:進化、設計、および実装-Steve D. Pate
  4. 実用的なファイルシステムの設計-ドミニクジャンパオロ
  5. ファイルシステムフォレンジック分析-ブライアンキャリア
  6. Linuxファイルシステム階層-BinhNguyen
  7. BTRFS:LinuxBツリーファイルシステム-OhadRodeh
  8. StegFS:Linux用のステガノグラフィファイルシステム-Andrew D. McDonald、Markus G. Kuhn

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

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

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

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

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

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

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

暗号化とネットワークセキュリティセキュリティのための名前空間、リモート攻撃からの保護セキュアな組み込み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. アート・オブ・メモリー・フォレンジック-マイケル・ヘイル・ライ、アンドリュー・ケース、ジェイミー・レビー、アーロン・ウォルターズ
  6. 実用的なリバースエンジニアリング-ブルース・ダング、アレクサンドル・ガゼット、エリアス・バシャラニー
  7. 実用的なマルウェア分析-MichaelSikorski 、Andrew Honig
  8. Linuxの最大のセキュリティ:Linuxサーバーを保護するためのハッカーガイド-匿名
  9. Linuxセキュリティ-CraigHunt
  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. 初心者はLinux0.11ソース(20,000行未満のソースコード)から始めます。Linux 0.11と比較して、20年の開発の後、Linuxは非常に巨大で、複雑になり、習得が困難になりました。しかし、デザインコンセプトと主要な構造に根本的な変更はありません。Linux 0.11を学ぶことは、依然として重要な実践的意義を持っています。
  2. カーネルハッカーの必読=>Linux_source_dir/Documentation/*
  3. 少なくとも1つのカーネルメーリングリストに登録してアクティブにする必要があります。カーネル初心者から始めましょう。
  4. 完全なソースコードを読む必要はありません。カーネルAPIとその使用法に慣れたら、関心のあるサブシステムのソースコードから直接開始します。また、独自のプラグアンドプレイモジュールを作成してカーネルを試すこともできます。
  5. デバイスドライバーの作成者は、専用のハードウェアを用意することでメリットが得られます。RaspberryPiから始めます。
于 2015-01-05T15:03:42.817 に答える
31

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

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

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

于 2009-05-27T09:05:25.177 に答える
8

Linuxカーネル管理人プロジェクトをチェックしてください

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

于 2009-05-27T09:35:08.050 に答える
5

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

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

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

于 2009-05-27T08:59:19.607 に答える
1

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

于 2009-05-27T11:16:27.660 に答える
1

いくつかのリソース:

于 2013-10-31T11:56:28.140 に答える