我想学习lLinux内核编程。

这样做的出发点是什么?可以针对哪些更简单的问题?

有帮助吗?

解决方案

尽量让罗伯特·爱的Linux内核编程的书的保持。它非常简洁,易于遵循。

之后或一起,你可能想看看“深入理解Linux内核”。但我不会在早期阶段推荐它。

另外,看一下 Linux内核编程指南。由于很多可以从编程内核模块可以得知,该指南将帮助您。是的,对于大量的信息,请参阅“文档”内核源代码压缩包的子目录。

其他提示

**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 素性测试去随机化算法:

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 )

“自然既没有内核,也没有外壳;她同时就是一切”——约翰·沃尔夫冈·冯·歌德

读者应该熟悉 操作系统概念;对长时间运行的进程及其与短时间突发执行的进程的差异有一个公平的理解;容错同时满足软实时和硬实时约束。阅读时,理解和理解很重要 n/ack Linux 内核源代码在核心子系统中做出的设计选择。

线程[和]信号是一条依赖于平台的痛苦、绝望、恐怖和疯狂的踪迹(~安东尼·巴克斯特)。话虽如此,在深入研究内核之前,您应该成为一名自我评估的 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
  1. Linux内核开发 - 罗伯特·洛夫
  2. 了解 Linux 内核 - 丹尼尔·P。播威,马可·塞萨蒂
  3. Linux 内核设计的艺术 - 杨丽香
  4. 专业Linux内核架构 - 沃尔夫冈·毛雷尔
  5. UNIX操作系统的设计 - 莫里斯·J。巴赫
  6. 了解 Linux 虚拟内存管理器 - 梅尔·戈尔曼
  7. Linux 内核内部结构 - 蒂格兰·艾瓦齐安
  8. 嵌入式 Linux 入门 - 克里斯托弗·哈利南

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

“音乐无法陪伴你前进。你必须严格按照自己的能力来坚持下去,真正专注于情感或故事的那个小核心”。——黛比·哈利

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

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

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 设备驱动程序 - 乔纳森·科贝特、亚历山德罗·鲁比尼和格雷格·克罗-哈特曼
  2. 基本 Linux 设备驱动程序 - 斯里克里希南·文卡特斯瓦兰
  3. 编写 Linux 设备驱动程序 - 杰里·库珀斯坦
  4. Linux 内核模块编程指南 - 彼得·杰伊·萨尔兹曼、迈克尔·布里安、奥里·波梅兰兹
  5. Linux PCMCIA 程序员指南 - 大卫·海因兹
  6. Linux SCSI 编程指南 - 海科·艾伯费尔特
  7. POSIX 操作系统串行编程指南 - 迈克尔·R。甜的
  8. Linux 图形驱动程序:一个介绍 - 史蒂芬·马尔切森
  9. Linux USB 设备驱动程序编程指南 - 德特勒夫·弗利格尔
  10. Linux 内核设备模型 - 帕特里克·莫切尔

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

“称其为氏族、称其为网络、称其为部落、称其为家庭:无论您称之为什么,无论您是谁,都需要一个。” - 简·霍华德(Jane Howard)

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

static inline int sk_hashed(const struct sock *sk)
{
        return !sk_unhashed(sk);
} 
  1. 了解 Linux 网络内部结构 - 克里斯蒂安·本韦努蒂
  2. Linux 内核网络:实施与理论 - 拉米·罗森
  3. UNIX网络编程 - W.理查德·史蒂文斯
  4. Linux 网络编程权威指南 - 凯尔·戴维斯、约翰·W.内森·约科姆·特纳
  5. Linux TCP/IP 堆栈:嵌入式系统网络 - 托马斯·F.赫伯特
  6. Linux Socket 编程示例 - 沃伦·W.同性恋
  7. Linux 高级路由和流量控制 HOWTO - 伯特·休伯特

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

除非在与它沟通时准确说出自己的意思,否则必然会产生麻烦。~艾伦·图灵,关于计算机

布莱恩·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. Linux 调试和性能调优 - 史蒂夫·贝斯特
  2. Linux应用程序调试技术 - 奥勒良·梅林特
  3. 使用GDB调试:GNU 源代码级调试器 - 罗兰·H.佩施
  4. 调试嵌入式Linux - 克里斯托弗·哈利南
  5. 使用 GDB、DDD 和 Eclipse 进行调试的艺术 - 诺曼·S。马特洛夫
  6. 为什么程序失败:系统调试指南 - 安德烈亚斯·泽勒
  7. 软件驱魔:调试和优化遗留代码的手册 - 比尔·布伦登
  8. 调试:查找最难以捉摸的软件和硬件问题 - 大卫·J。阿甘斯
  9. 思维调试:多学科方法 - 罗伯特·查尔斯·梅茨格
  10. 找到错误:错误程序之书 - 亚当·巴尔

文件系统 ( 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 文件系统 - 摩西酒吧
  2. Linux 文件系统 - 威廉·冯·哈根
  3. UNIX 文件系统:演变、设计和实施 - 史蒂夫·D.佩特
  4. 实用文件系统设计 - 多米尼克·詹保罗
  5. 文件系统取证分析 - 布赖恩·开利
  6. Linux 文件系统层次结构 - 平阮
  7. BTRFS:Linux B 树文件系统 - 奥哈德·罗德
  8. 斯特格FS: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"
  1. 黑客攻击:剥削的艺术 - 乔恩·埃里克森
  2. Rootkit 阿森纳:系统黑暗角落的逃脱与躲避 - 比尔·布伦登
  3. 黑客暴露:网络安全秘密 - 斯图尔特·麦克卢尔、乔尔·斯坎布雷、乔治·库尔茨
  4. 内核利用指南:攻击核心 - 恩里科·佩拉、马西米利亚诺·奥尔达尼
  5. 记忆取证的艺术 - 迈克尔·海尔·赖、安德鲁·凯斯、杰米·利维、艾伦·沃尔特斯
  6. 实用逆向工程 - Bruce Dang、Alexandre Gazet、Elias Bachaalany
  7. 实用恶意软件分析 - 迈克尔·西科尔斯基、安德鲁·霍尼格
  8. 最大的 Linux 安全性:保护 Linux 服务器的黑客指南 - 匿名的
  9. Linux安全 - 克雷格·亨特
  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行)。经过20年的发展,与Linux 0.11相比,Linux已经变得非常庞大、复杂、难学。但设计理念和主体结构没有根本性变化。学习Linux 0.11还是有重要的现实意义的。
  2. 内核黑客必读 => Linux_source_dir/Documentation/*
  3. 您应该订阅并活跃至少一个内核邮件列表。从...开始 内核新手.
  4. 您不需要阅读完整的源代码。一旦熟悉了内核 API 及其用法,就可以直接从您感兴趣的子系统的源代码开始。您还可以开始编写自己的即插即用模块来试验内核。
  5. 设备驱动程序编写者将受益于拥有自己的专用硬件。从...开始 树莓派.

查核 Linux内核看门人计划

  

“”我们去通过Linux内核源代码,做代码审查,修正了无人维护的代码和做其他的清理和API转换。这是一个良好的开端内核黑客攻击。“

我不得不说:“学习C”。 :)

试试这个免费的在线图书。

<强> Linux内核模块编程指南 http://www.linuxhq.com/guides/LKMPG/mpg.html

检查kernelnewbies.org,订阅Kernelnewbies邮件列表,得到了irc.oftc.org #kernelnewbies

一些资源:

  • 书:Robert Love,Linux 内核开发,第三版
  • 书:Corbet、Rubini、Linux 设备驱动程序,第 3 版(免费版 这里)
  • 书:Linux 内核简述(免费版 这里)
  • 免费材料提供者 自由电子
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top