私は個人的な喜びのためにカーネルの内部修正、パッチ適用、デバイスドライバ、モジュールの作業に興味があります。
経験豊富なプログラマーのためのカーネルハッキングに関する包括的なリソースはありますか?
答え1
**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
覚えながら頭を澄んで保ちましょう。コードは文学ではありません。
残りは物事、感情、イメージ、精神的な絵、記憶、さらにはアイデアではありません。それは機能です。一種のコース。 「より大きな」ものの機能として説明できる人生の一側面。だからそれは他のどんなものとも「分離」されていないようです。刀の機能(何かを切るもの)が実際に刀自体とは別ではないかのように。この機能は、現在使用中であっても使用されていなくても分離されない場合があります。
Solovay Strassen疎水性試験非ランダム化アルゴリズム:
読書は反論して反論するものではなく、信じて受け入れるものでもなく、会話や言葉を見つけることでもありません。ある本は味わわなければならず、ある本は飲み込まなければならず、ある本は噛んで消化しなければならない。言い換えれば、ある本は部分的に読まなければならず、ある本は好奇心なしに読まなければならず、ある本は好奇心なしに読まなければならない。 。すべて読んでください。 、勤勉で集中しなさい。
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();
}
}
CoreLinux(5 -> 1 -> 3 -> 2 -> 7 -> 4 -> 6)
「自然にはコアもシェルもありません。自然は同時にすべてです。」 - ヨハン・ヴォルフガング・フォン・ゲーテ
読者は次のことに精通している必要があります。オペレーティングシステムの概念;長期実行プロセスと短期間で実行されるプロセスとの違いを公平に理解します。フォールトトレランスは、ソフトとハードのリアルタイム制約の両方を満たします。読みながら、n/ack
コアサブシステムでLinuxカーネルソースコードが選択したデザインを理解することが重要です。
Thread [and] Signalは、プラットフォームに依存する痛み、絶望、恐怖、狂気の道です(~Anthony Baxter)。しかし、カーネルに飛び込む前に、あなたは自分で評価できる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カーネルソースコードの美しさと芸術は、使用された意図的なコード難読化にあります。これは、複数のタスクを含む計算の意味をきれいでエレガントな方法で伝えるために必要なことがよくあります。これは、マルチコアアーキテクチャ用のコードを書くときに特に当てはまります。
ビデオ講義リアルタイムシステムで、ジョブのスケジュール、メモリ圧縮、メモリバリア、界面活性剤
#ifdef __compiler_offsetof
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
#else
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
- Linuxカーネルの開発-ロバート・ラブ
- Linuxカーネルについて学ぶ-ダニエルP.ボビー、マルコセサティ
- Linuxカーネルデザインの芸術-ヤンリシャン
- プロのLinuxカーネルアーキテクチャ-ヴォルフガングマウラー
- UNIXオペレーティングシステムの設計-モリスJ.バッハ
- Linux仮想メモリマネージャについて-メルゴーマン
- Linuxカーネルの内部構造-ティグラン・アバジアン
- 組み込みLinuxの起動-クリストファー・ハリナン
Linuxデバイスドライバ(1 -> 2 -> 4 -> 3 -> 8 -> ...)
「音楽はあなたと同行しません。あなたはそれを伴う能力に厳密に依存し、感情や物語の小さなコアに本当に集中する必要があります。」 ——デビーハリー
あなたの使命は、基本的にハードウェアデバイスとソフトウェアカーネルの間に高速通信インターフェースを構築することです。デバイスの動作、デバイスの制御およびデータ状態、ならびに提供されている物理チャネルを理解するには、ハードウェアリファレンスデータシート/マニュアルを読む必要があります。長期的には、特定のアーキテクチャのアセンブリ知識を持ち、VHDLやVerilogなどのVLSIハードウェア記述言語を理解するのに役立ちます。
尋ねる:しかし、なぜハードウェア仕様を読むべきですか?
ㅏ:「ソフトウェアは炭素とシリコンの間のギャップを埋めることができないからです」 - 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;
}
- Linuxデバイスドライバ-ジョナサン・コベット(Jonathan Corbett)、アレッサンドロ・ルビニ(Alessandro Roubini)、グレッグ・クロウハートマン(Greg Crow-Hartman)
- 基本的なLinuxデバイスドライバ-スリクリシュナンベンカテスワラン
- Linuxデバイスドライバの作成-ジェリー・クーパースタイン
- Linuxカーネルモジュールプログラミングガイド-ピーター・ジェイ・ザルツマン、マイケル・ブリアン、アヒル・ポメランツ
- Linux PCMCIAプログラマガイド-デビッド・ハインズ
- Linux SCSIプログラミングガイド-ハイコエバーフェルト
- POSIXオペレーティングシステムシリアルプログラミングガイド-マイケルスイート
- Linuxグラフィックドライバ:はじめに-スティーブン・マーチソン
- Linux USBデバイスドライバプログラミングガイド-デトレフ・フリグル
- Linuxカーネルデバイスモデル-パトリック・モッチェル
カーネルネットワーク(1 -> 2 -> 3 -> ...)
「クランと呼んでも、ネットワークと呼んでも、部族と呼んでも、家族と呼んでも、誰と呼んでも、1つが必要です」 - ジェーンハワード
カーネルのパケット通過を理解することは、カーネルネットワーキングを理解するために重要です。 NetfilterやIPSecの内部などを理解するには、これを理解する必要があります。 Linuxカーネルネットワーク層の最も重要な2つの構造は次のとおりstruct sk_buff
です。struct net_device
static inline int sk_hashed(const struct sock *sk)
{
return !sk_unhashed(sk);
}
- Linuxネットワークの内部構造の理解-クリスチャン・ベンベヌーティ
- Linuxカーネルネットワーキング:実装と理論-ラミーローゼン
- UNIXネットワークプログラミング-W.リチャード・スティーブンス
- Linuxネットワークプログラミングのための明確なガイド-カイル・デイビス、ジョン・W・ターナー、ネイサン・ヨコム
- Linux TCP/IP スタック: 組み込みシステムのネットワーキング-トーマスF.ハーバート
- Linuxソケットプログラミングの例-ウォーレンゲイ
- Linux高度なルーティングとトラフィック制御方法-バート・ヒューバート
カーネルのデバッグ(1 -> 4 -> 9 -> ...)
人々がコンピュータとコミュニケーションをとるときに自分の意思を正確に表現できない場合、問題が発生するしかありません。 〜Alan Turing、コンピュータについて
Brian W. Kernighanは、「初心者のためのUnix」(1979)で、「最も効果的なデバッグツールは、printステートメントを慎重に配置することと慎重に考えることです」と述べました。何を収集するかを知ることは、迅速な診断のために正しいデータをすばやく取得するのに役立ちます。偉大なコンピュータサイエンティストのEdsger Dijkstra氏は、テストでエラーがあることを証明することはできますが、エラーがないことを証明することはできないと言ったことがあります。良い調査慣行は、問題を迅速に解決する必要性、技術を開発する必要性、およびその分野の専門家の効果的な活用の間でバランスをとる必要があります。
時々あなたが床にぶつかったときに何も動作しないように見え、すべてのオプションが消えます。その後、実際のデバッグが開始されます。間違いは、効果のないソリューションにこだわるのに必要な休息を提供する可能性があります。
ビデオ講義カーネルのデバッグと分析情報、コアダンプ分析、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
*/
- Linuxのデバッグとパフォーマンスのチューニング-スティーブベスト
- Linuxアプリケーションデバッグ技術-アウレリアンメリント
- GDBを使用したデバッグ:GNUソースレベルデバッガ-ローランドH.ペシ
- 組み込みLinuxのデバッグ-クリストファー・ハリナン
- GDB、DDD、Eclipseを使用したデバッグ技術-ノーマンマトロープ
- プログラムが失敗する理由:システムデバッグガイド-アンドレアスゼラー
- ソフトウェアエクソシズム:レガシーコードのデバッグと最適化のためのハンドブック-ビル・ブレンデン
- デバッグ:最もわかりにくいソフトウェアとハードウェアの問題を見つける-デビッド・J・アルガンス
- マインドデバッグ:多学的アプローチ-ロバート・チャールズ・メッツガー
- バグを探す:悪いプログラムに関する本-アダムバー
ファイルシステム(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);
}
- Linuxファイルシステム-モーセバー
- Linuxファイルシステム-ヴィルヘルム・フォンハーゲン
- UNIXファイルシステム:進化、設計、実装-スティーブD.フェイト
- 実用的なファイルシステム設計-ドミニク・ジアンパオロ
- ファイルシステムフォレンジック分析-ブライアンキャリア
- Linuxファイルシステム階層-空のグエン
- BTRFS:Linux Bツリーファイルシステム-オーハードロード
- StegFS:Linux用ステガノグラフィックファイルシステム-アンドリューD.マクドナルド、マーカスG.クーン
安全(1 -> 2 -> 8 -> 4 -> 3 -> ...)
「UNIXは、ユーザーが愚かなことを防ぐようには設計されていません。なぜなら、ユーザーは賢明なことを防ぐことができるからです。」 — ダググウィン
どんなスキルも使わないと効果的ではありません。技術が変わるにつれて、道徳も変わります。
」F×S=k「自由と安全の産物は不変です.―ニベンの法則
暗号化はオンライン信頼の基礎を形成します。ハッキングは、技術的、物理的、または人的要素を使用してセキュリティ管理を利用することです。実行中の他のプログラムからカーネルを保護することは安全で信頼性の高いシステムに向けた最初のステップですが、これだけでは不十分です。異なるユーザースペースアプリケーション間に一定レベルの保護も存在する必要があります。エクスプロイトはローカルまたはリモートサービスをターゲットにすることができます。
「無差別的な力で運命をハッキングすることはできません。バックドア、人生に通じる通路が必要です」 ——クライド頭数字
コンピュータは問題を解決するのではなく、ソリューションを実装します。すべての後ろに不確実性アルゴリズムコードに決める精神。 --/var/log/dmesg
ビデオ講義暗号化とネットワークセキュリティ、セキュリティネームスペース、リモート攻撃から保護、セキュリティ組み込みLinux
env x='() { :;}; echo vulnerable' bash -c "echo this is a test for Shellsock"
- ハッキング: 搾取の技術-ジョン・エリクソン
- Rootkit Armory:システムの暗い隅から脱出- ビル・ブレンデン
- 公開されたハッカー:サイバーセキュリティ秘密-スチュアート・マクルア、ジョエル・スカムブレイ、ジョージ・カーツ
- カーネル悪用ガイド:コア攻撃-エンリコ・フェラ、マシミリアーノ・オルダニ
- メモリフォレンジックの芸術-マイケル・ヘイレイ、アンドリュー・キス、ジェイミー・レヴィ、アラン・ウォルターズ
- 実用的なリバースエンジニアリング-ブルース党、アレクサンドルガーゼ、エリアスバッチャーアラニ
- 実用的なマルウェア分析-マイケル・シコルスキー、アンドリュー・ホニーグ
- 最大Linuxセキュリティ:Linuxサーバーを保護するためのハッカーガイド-匿名
- Linuxセキュリティ-クレイグハンター
- 実際の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
- 初心者からLinux 0.11ソースコード(ソースコードは20,000行未満)。 20年の開発の終わりに、Linux 0.11と比較すると、Linuxは非常に大きく、複雑で、学びにくくなりました。しかし、デザインコンセプトと主な構造は根本的に変わっていません。 Linux 0.11を学ぶことは依然として重要な実用的な意味を持ちます。
- カーネルハッカーが必ず読むべき本=>
Linux_source_dir/Documentation/*
- 少なくとも1つのカーネルメーリングリストに参加して活動する必要があります。から始まるカーネルの新機能。
- 完全なソースコードを読む必要はありません。カーネルAPIと使い方に慣れたら、興味のあるサブシステムのソースコードから直接始めることができます。独自のプラグアンドプレイモジュールを作成してカーネル実験を開始することもできます。
- デバイスドライバの作成者は、独自の専用ハードウェアを保持することで利点を得ることができます。から始まるラズベリーパイ。
答え2
Linuxカーネルの新機能素晴らしいリソースです。
答え3
「を読んでください。Linuxカーネルの簡単な紹介「グレッグ・クロハ・ハートマン(Greg Kroah-Hartman)」Linuxカーネルについて学ぶ「ロバート・ラブ(Robert Love)」の必読書です。 :)
答え4
よりLinux文書化プロジェクト。特に「Linuxカーネルモジュールガイド」です。