我有兴趣修改内核内部结构,应用补丁,处理设备驱动程序和模块,这是我个人的乐趣。
是否有针对经验丰富的程序员的全面的内核黑客资源?
我有兴趣修改内核内部结构,应用补丁,处理设备驱动程序和模块,这是我个人的乐趣。
是否有针对经验丰富的程序员的全面的内核黑客资源?
Answers:
**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
。警惕地阅读并记住:代码不是文学。
剩下的不是事物,情感,图像,心理图片,记忆,甚至是想法。它是一个功能。某种过程。生活的一个方面可以描述为“更大”事物的功能。因此,似乎它与其他东西并不是真正的“分离”。实际上,就像刀子的功能一样-切割东西-与刀子本身并不分离。该功能目前可能正在使用或可能未使用,但可能永远不会分开使用。
阅读时不要矛盾和混淆;也不相信和理所当然;也找不到谈话和话语;但要权衡和考虑。有些书是要品尝的,其他的是要吞咽的,而有些则是要咀嚼和消化的:也就是说,有些书只能部分阅读,而有些书则要好奇阅读,但不要好奇,而有些书要全部阅读。 ,并尽职尽责。
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 Kernel源代码的美丽和艺术在于随之而来的故意的代码混淆。通常需要以简洁明了的方式传达涉及两个或多个运算的计算含义。在编写用于多核体系结构的代码时尤其如此。
#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-> ...)
“音乐并不能帮助您。您必须严格按照自己的能力来做到这一点,才能真正专注于情感或故事的那一小部分。” -黛比·哈里
您的任务基本上是在硬件设备和软件内核之间建立高速通信接口。您应该阅读硬件参考数据表/手册,以了解设备的行为及其控制和数据状态以及提供的物理通道。从长远来看,您对特定体系结构的汇编知识以及对VLSI硬件描述语言的充分了解将可以为您提供帮助,例如VHDL或Verilog。
问:但是,为什么我必须阅读硬件规格?
答:因为“软件无法弥合碳和硅的鸿沟”-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-> 2-> 3-> ...)
“称它为氏族,称其为网络,称其为部落,称其为家庭:无论您叫什么,无论您是谁,都需要一个。”-简·霍华德
了解内核中的数据包漫游是了解内核网络的关键。如果我们想了解Netfilter或IPSec内部以及其他内容,则必须了解它。linux内核网络层的两个最重要的结构是:struct sk_buff
和struct net_device
static inline int sk_hashed(const struct sock *sk)
{
return !sk_unhashed(sk);
}
内核调试(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
*/
文件系统(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-> 2-> 8-> 4-> 3-> ...)
“ UNIX并非旨在阻止其用户执行愚蠢的操作,因为这也将阻止他们执行聪明的操作”。—道格·格温(Doug Gwyn)
如果不使用任何技术,则无济于事。道德随着技术而改变。
“ F×S = k ”自由与安全的乘积是一个常数。-尼文定律
密码学构成了在线信任的基础。黑客正在利用技术,物理或基于人的元素中的安全控制。保护内核免受其他正在运行的程序的侵害,是朝着建立安全,稳定的系统的第一步,但这显然是不够的:在不同的用户区域应用程序之间也必须存在一定程度的保护。漏洞可以针对本地或远程服务。
“您无法破坏自己的命运,蛮力……您需要一扇后门,一条通向生活的通道。” ― Clyde Dsouza
计算机不解决问题,而是执行解决方案。在每个非确定性算法代码的背后,都有一个坚定的头脑。 -/ 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)
“就像wine一样,内核编程的掌握程度会随着时间而成熟。但是,与wine不同,它在过程中会变得更甜。” -劳伦斯·穆切卡(Lawrence Mucheka)
您可能不认为程序员是艺术家,但是编程是一个极富创造力的职业。这是基于逻辑的创造力。计算机科学教育不能使任何人成为专家程序员,就像学习画笔和颜料可以使某人成为专家画家一样。如您所知,知道路径和走路径是有区别的。卷起袖子并掌握内核源代码对您至关重要。最后,借助您由此获得的内核知识,无论您走到哪里,都将发光。
不成熟的编码员会模仿;成熟的编码员偷窃;糟糕的编码人员会掩盖他们的工作,而好的编码人员会使它变得更好,或者至少有所不同。优秀的编码员将盗窃案焊接成一种独特的感觉,与被撕破的感觉完全不同。
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设备驱动程序是另一个很好的资源。这将为您提供另一种进入内部运作方式的方法。从序言:
从表面上看,这是一本有关为Linux系统编写设备驱动程序的书。当然,这是一个值得的目标。新硬件产品的流量可能不会很快放缓,并且有人将不得不使所有这些新小工具都可以在Linux上使用。但是本书还涉及Linux内核如何工作以及如何使其工作适应您的需求或兴趣。Linux是一个开放系统。希望通过这本书,它对更多的开发人员社区更加开放和易于使用。
Linux Kernel 2.4 Internals是另一个在线资源。从启动开始,似乎采取了一种非常“基础”的方法。这里是目录:
而且,为了使它更甜蜜,有一个由Robert Love发行的新Linux Kernel Development第三版,Slashdot对此进行了评论。