Linux 内核:好的初学者教程

Ada*_*tan 53 linux kernel linux-kernel

我对修改内核内部结构、应用补丁、处理设备驱动程序和模块感兴趣,为了我个人的乐趣。

是否有针对内核黑客的综合资源,供有经验的程序员使用?

man*_*m-n 33

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

KERN_WARN_CODING_STYLE: Do not Loop unless you absolutely have to.
Run Code Online (Sandbox Code Playgroud)

未初始化的推荐书籍void *i

“人只有经历了一定的生活才能理解书,或者至少没有人能理解一本深刻的书,直到他至少看到并体验了其中的一部分内容”。——埃兹拉·庞德

一千码英里的旅程必须从一步开始。如果您对从以下哪本书开始感到困惑,请不要担心,选择您所选择的任何一本。并非所有流浪的人都迷路了。由于所有道路最终都连接到高速公路,您将在内核旅程中探索新事物,随着页面前进而不会遇到任何死胡同,并最终连接到code-set. 以警觉的头脑阅读并记住:代码不是文学

留下的不是事物、情感、图像、心理图片、记忆,甚至是想法。它是一个函数。某种过程。生活的一个方面,可以被描述为“更大”的东西的功能。因此,它似乎并没有真正与其他东西“分开”。就像刀的功能——切割东西——实际上并不是与刀本身分开的。该功能目前可能正在使用,也可能未在使用,但它可能永远不会分开。

Solovay Strassen 用于素性测试的去随机化算法

用于素性检验的 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();
        }
}
Run Code Online (Sandbox Code Playgroud)

核心 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;
}
Run Code Online (Sandbox Code Playgroud)

Linux 内核源代码的美妙和艺术在于其使用的故意代码混淆。这通常需要以简洁优雅的方式传达涉及两个或多个操作的计算意义。在为多核架构编写代码时尤其如此。

实时系统任务调度内存压缩内存屏障 SMP视频讲座

#ifdef __compiler_offsetof
#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
#else
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
Run Code Online (Sandbox Code Playgroud)
  1. Linux 内核开发- Robert Love
  2. 了解 Linux 内核- Daniel P. Bovet、Marco Cesati
  3. Linux 内核设计的艺术-杨丽香
  4. 专业的 Linux 内核架构- Wolfgang Mauerer
  5. UNIX 操作系统的设计- Maurice J. Bach
  6. 了解 Linux 虚拟内存管理器- Mel Gorman
  7. Linux 内核内部结构- Tigran Aivazian
  8. 嵌入式 Linux 入门- Christopher Hallinan

Linux 设备驱动程序( 1 -> 2 -> 4 -> 3 -> 8 -> ... )

“音乐不会带你走。你必须严格按照你的能力来真正地专注于情感或故事的小内核”。——黛比·哈里

你的任务基本上是在硬件设备和软件内核之间建立一个高速通信接口。您应该阅读硬件参考数据表/手册以了解设备的行为及其控制和数据状态以及提供的物理通道。从长远来看,您对特定架构的汇编知识和对 VHDL 或 Verilog 等 VLSI 硬件描述语言的全面了解将对您有所帮助。

Q : 但是,为什么我必须阅读硬件规格?

:因为,“软件无法弥合碳和硅之间的鸿沟”- 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;
}
Run Code Online (Sandbox Code Playgroud)
  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éphane Marchesin
  9. Linux USB 设备驱动程序编程指南- Detlef Fliegl
  10. Linux 内核设备模型- Patrick Mochel

内核网络( 1 -> 2 -> 3 -> ... )

“称其为氏族,称其为网络,称其为部落,称其为家庭:无论您如何称呼它,无论您是谁,您都需要一个。” ——简·霍华德

了解内核中的数据包演练是了解内核网络的关键。如果我们想了解 Netfilter 或 IPSec 内部结构等,就必须了解它。linux内核网络层的两个最重要的结构是:struct sk_buffstruct net_device

static inline int sk_hashed(const struct sock *sk)
{
        return !sk_unhashed(sk);
} 
Run Code Online (Sandbox Code Playgroud)
  1. 了解 Linux 网络内部结构- Christian Benvenuti
  2. Linux 内核网络:实现和理论- Rami Rosen
  3. UNIX 网络编程- W. Richard Stevens
  4. Linux 网络编程权威指南- Keir Davis、John W. Turner、Nathan Yocom
  5. Linux TCP/IP 堆栈:嵌入式系统网络- Thomas F. Herbert
  6. Linux Socket 编程示例- Warren W. Gay
  7. Linux 高级路由和流量控制 HOWTO - Bert Hubert

内核调试( 1 -> 4 -> 9 -> ... )

除非在与它交流时准确地说出它的意思,否则必然会导致麻烦。~艾伦图灵,关于计算机

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
 */
Run Code Online (Sandbox Code Playgroud)
  1. Linux 调试和性能调优- Steve Best
  2. Linux 应用程序调试技术- Aurelian Melinte
  3. 使用 GDB 进行调试:GNU 源代码级调试器- Roland H. Pesch
  4. 调试嵌入式 Linux - Christopher Hallinan
  5. 使用 GDB、DDD 和 Eclipse 进行调试的艺术- Norman S. Matloff
  6. 为什么程序会失败:系统调试指南- Andreas Zeller
  7. 软件驱魔:调试和优化遗留代码的手册- Bill Blunden
  8. 调试:查找最难以捉摸的软件和硬件问题- David J. Agans
  9. 通过思考进行调试:一种多学科方法-罗伯特·查尔斯·梅茨格
  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);
}
Run Code Online (Sandbox Code Playgroud)
  1. Linux 文件系统- Moshe Bar
  2. Linux 文件系统- William Von Hagen
  3. UNIX 文件系统:进化、设计和实现- Steve D. Pate
  4. 实用的文件系统设计- Dominic Giampaolo
  5. 文件系统取证分析- Brian Carrier
  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

密码学和网络安全安全命名空间远程攻击防护安全嵌入式 Linux 的视频讲座

env x='() { :;}; echo vulnerable' bash -c "echo this is a test for Shellsock"
Run Code Online (Sandbox Code Playgroud)
  1. 黑客:剥削的艺术-乔恩·埃里克森
  2. Rootkit 军械库:系统黑暗角落的逃避与逃避- 比尔·布伦登
  3. 黑客暴露:网络安全秘密- Stuart McClure、Joel Scambray、George Kurtz
  4. 内核开发指南:攻击内核- Enrico Perla, Massimiliano Oldani
  5. 记忆取证的艺术- Michael Hale Ligh、Andrew Case、Jamie Levy、AAron Walters
  6. 实用逆向工程- Bruce Dang、Alexandre Gazet、Elias Bachaalany
  7. 实用恶意软件分析- Michael Sikorski、Andrew Honig
  8. 最大 Linux 安全性:保护 Linux 服务器的黑客指南-匿名
  9. Linux 安全- Craig H

    • 谢谢!这是一个非常全面的答案。会看看 (2认同)

Hem*_*ant 12

Linux Kernel Newbies是一个很好的资源。


wzz*_*zrd 5

我建议您阅读Greg Kroah-Hartman 的“ Linux Kernel in a Nutshell ”和Robert Love 的“ Understanding the Linux Kernel ”。必读:)

  • http://www.kroah.com/lkn/ - 免费在线 (2认同)