個人的な楽しみのために、カーネル内部の修正、パッチの適用、デバイスドライバーとモジュールの処理に興味があります。
経験豊富なプログラマ向けのカーネルハッキング用の包括的なリソースはありますか?
個人的な楽しみのために、カーネル内部の修正、パッチの適用、デバイスドライバーとモジュールの処理に興味があります。
経験豊富なプログラマ向けのカーネルハッキング用の包括的なリソースはありますか?
回答:
**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
「本は、ある程度の寿命があるまで、または少なくともその内容の一部を見て生きるまで、誰も深い本を理解しない限り、本を理解しない」。–エズラポンド
数千コードマイルの旅は、最初の一歩から始めなければなりません。次の本のどれから始めるべきかについて混乱している場合、心配しないで、あなたの選択のいずれかを選んでください。さまようすべての人が失われるわけではありません。すべての道路が最終的に高速道路に接続するには、ページが任意の行き止まりを満たさずに進むにつれて、あなたのカーネルの旅に新しいものを探求、そして最終的に接続しますcode-set
。注意して読み、覚えてください:コードは文学ではありません。
残されているのは、物や感情、イメージ、精神的な絵、記憶、あるいはアイデアではありません。機能です。ある種のプロセス。「より大きな」何かの機能として説明できる生命の側面。したがって、それは実際にはそれとは別のものではないようです。ナイフの機能のように-何かを切断する-実際には、ナイフ自体から分離されていません。この関数は現在使用されている場合と使用されていない場合がありますが、決して分離されることはありません。
素数性テストのためのSolovay Strassen Derandomizedアルゴリズム:
矛盾しないように読んでください。信じたり当たり前にしたりすることもありません。話や談話を見つけることも。しかし、重量を量り、考慮すること。味わう本もあれば、飲み込む本もあり、噛んで消化する本もあります。つまり、一部の本は部分的にしか読むことができず、他の本は読むことはできますが不思議ではなく、いくつかは完全に読むことです、そして勤勉と注意を払って。
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)
「自然にはカーネルもシェルもありません。彼女は一度にすべてです」-ヨハン・ヴォルフガング・フォン・ゲーテ
読者はオペレーティングシステムの概念に精通している必要があります。実行時間の長いプロセスと、実行のバーストが短いプロセスとの違いについての公正な理解。ソフトおよびハードのリアルタイム制約を満たしながら、フォールトトレランス。読みながらn/ack
、コアサブシステムのLinuxカーネルソースによって行われた設計選択を理解することが重要です。
スレッド[および]シグナルは、悲惨、絶望、恐怖、狂気のプラットフォーム依存の軌跡です(〜Anthony Baxte)。カーネルに飛び込む前に、自己評価型の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 Kernelソースの美しさと芸術は、一緒に使用される意図的なコード難読化にあります。これは、2つ以上の操作を含む計算上の意味をクリーンでエレガントな方法で伝えるためにしばしば必要になります。これは、マルチコアアーキテクチャのコードを記述する場合に特に当てはまります。
リアルタイムシステムに関するビデオ講義、タスクスケジューリング、メモリ圧縮、メモリバリア、 SMP
#ifdef __compiler_offsetof
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
#else
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
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-> 2-> 3-> ...)
「それを一族と呼び、ネットワークと呼び、部族と呼び、それを家族と呼びます。どんな呼び方でも、誰でも、それが必要です。」-ジェーン・ハワード
カーネルのパケットウォークスルーを理解することは、カーネルネットワーキングを理解するための鍵です。NetfilterやIPSecの内部構造などを理解したい場合、それを理解することは必須です。Linuxカーネルのネットワーク層の2つの最も重要な構造である:struct sk_buff
とstruct net_device
static inline int sk_hashed(const struct sock *sk)
{
return !sk_unhashed(sk);
}
カーネルデバッグ(1-> 4-> 9-> ...)
それと通信する際に、自分が何を意味するのかを正確に述べない限り、トラブルは結果に結びつきます。〜Alan Turing、コンピューターについて
Brian W. Kernighanは、Unix for Beginners(1979)の論文で、「最も効果的なデバッグツールは、慎重に考えられ、慎重に配置された印刷ステートメントと相まって」と述べています。何を収集するかを知ることは、迅速な診断のために適切なデータを迅速に取得するのに役立ちます。偉大なコンピューター科学者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
*/
ファイルシステム(1-> 2-> 6-> ...)
「少なくとも、ファイルシステムと結合されているため、仮想メモリが必要でした」。-ケン・トンプソン
UNIXシステムでは、すべてがファイルです。何かがファイルではない場合、名前付きパイプとソケットを除くプロセスです。ファイルシステムでは、ファイルはinode
、ファイルを構成する実際のデータに関する情報を含む一種のシリアル番号で表されます。Linux Virtual File System 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-> 2-> 8-> 4-> 3-> ...)
「UNIXは、ユーザーが愚かなことをするのを防ぐようには設計されていません。—ダグ・グウィン
使用しないと機能しません。倫理はテクノロジーによって変化します。
" F×S = k "自由とセキュリティの積は一定です。-ニーブンの法則
暗号化は、オンラインでの信頼の基礎を形成します。ハッキングは、技術的、物理的、または人間ベースの要素のいずれかでセキュリティコントロールを悪用しています。他の実行中のプログラムからカーネルを保護することは、安全で安定したシステムへの第一歩です。しかし、これは明らかに十分ではありません。異なるユーザーランドアプリケーション間でもある程度の保護が必要です。エクスプロイトは、ローカルまたはリモートのサービスを標的にすることができます。
「運命、ブルートフォースをハックすることはできません...バックドア、Lifeへのサイドチャンネルが必要です。」 -クライド・ドソーザ
コンピューターは問題を解決するのではなく、解決策を実行します。すべての非決定的アルゴリズムコードの背後には、決心があります。 -/ var / log / dmesg
ビデオ講義暗号とネットワークセキュリティ上、セキュリティのための名前空間、リモート攻撃に対する保護、組み込みLinuxをセキュア
env x='() { :;}; echo vulnerable' bash -c "echo this is a test for Shellsock"
カーネルソース(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_source_dir/Documentation/*
Linux Kernel Newbiesは素晴らしいリソースです。
Greg Kroah-Hartman による「Linux Kernel in a Nutshell」およびRobert Loveによる「Linux Kernelの理解」を読むことをお勧めします。読む必要があります:)
Linuxデバイスドライバーも別の優れたリソースです。それはあなたに内なる働きを得る別の方法を与えるでしょう。序文から:
これは、表面上は、Linuxシステム用のデバイスドライバーの作成に関する本です。もちろん、それは価値のある目標です。新しいハードウェア製品の流れはすぐに遅くなる可能性は低く、誰かがこれらの新しいガジェットをすべてLinuxで動作させる必要があります。しかし、この本はまた、Linuxカーネルがどのように機能するか、そしてその動作をあなたのニーズや興味に適応させる方法についても書いています。Linuxはオープンシステムです。この本を使用すると、よりオープンで、開発者のより大きなコミュニティにとってアクセスしやすくなります。
The Linux Documentation Projectをご覧ください。特に「Linuxカーネルモジュールガイド」。
Linux Kernel 2.4 Internalsは、もう1つのオンラインリソースです。起動から始めて、かなり「ゼロ」のアプローチを取るようです。ここに目次:
そして、さらに甘くするために、Robert Love outによる新しいLinux Kernel Development Third Editionがあり、Slashdotがレビューをしています。
Claudia SalzbergらによるLinux Kernel Primerから始めます。初心者向けの良いものです。ロバート・ラブの本は間違いなく初心者が始めるべき本ではありません。後半の本は中級以上です。