写给Linux内核新手-关于Linux内核学习的误区
-----感觉这篇文章不错,有非常多借鉴的地方,so转载过来了
先说句正经的:其实我没资格写这篇文章,因为自己也就一两个月以来才开始有所领悟的。因此,这里和其说是关于Linux内核学习的经验,不如说是自己的教训吧,希望不要扔鸡蛋砸我^_^
常常有人问:我想学习内核,需要什么基础吗?Linus Torvalds本人是这样回答的:你必须使用过Linux。 这个……还是有点太泛了吧,我想下面几个基础可能还是需要的,尽管不一定必需:
1, 关于操作系统理论的最初级的知识。不必通读并理解《操作系统概念》《现代操作系统》等巨著,但总要知道分时(time-shared)和实时(real-time)的差别是什么,进程是个什么东西,CPU和系统总线、内存的关系(非常粗略即可),等等。
2, 关于C语言。不必已非常精通C语言,只要能熟练编写C程式,能看懂链表、散列表等数据结构的C实现,用过gcc编译器,就能了。当然,如果已精通C语言显然是大占便宜的。
3, 关于CPU的知识。这块儿能在学习内核过程中补,但这样的话你就需要看讲解非常周详的书,比方后面将会提到的《情景分析》。你是否熟悉Intel 80386 CPU?尝试着回答这几个问题来判断一下:1)说出80386的中断门和陷阱门的差别;2)说出保护模式和实模式的差别;3)多处理器机器上,普通的读-改-写回一块内存这样的动作,为什么需要特别的手段来保护。等等。讲解基于其他CPU的Linux内核的书,目前好象只有一本《IA64Linux内核:设计和实现》──也还是Intel的,其他都是讲解基于IA32的。
以上算是知识方面吧,如果还要再补充一条,我想就是:动手编译过内核。
好了,我们接下来走。好多人装上Linux之后,第一件事找到内核源码所在的路径,打开一个C程式文件,开始哗哗哗翻页,看看大名鼎鼎的Linux内核代码到底长啥模样──然后关闭。这是可理解的,但却不是学习的方法。刚开始,必须从读书入手。至少要对内核有一个Overview之后,才有可能带着问题去试图阅读原始码本身。 下面就讲一下我读过的几本书:
1, 《Linux内核设计和实现》,英文名Linux Kernel Development(所以有人叫他LKD),机械工业出版社,¥35, 美国Robert Love著,陈莉君译者。 评说:
此书是当今首屈一指的入门最佳图书。作者是为2.6内核加入了抢占的人,对调度部分非常精通,而调度是整个系统的核心,因此本书是非常权威的。这本书讲解浅显易懂,全书没有列举一条汇编语句,不过给出了整个Linux操作系统2.6内核的概观,使你能通过阅读迅速获得一个overview。而且对内核中较为混乱的部分(如下半部),他的讲解是最透彻的。对没怎么深入内核的人来说,这是强烈推荐的一本书。
翻译:翻译水平、负责任程度都不错,不过印刷存在一些错误。买了此书的朋友能参考我在Linux高级应用版的《Linux内核设计和实现中文版勘误》:
http://bbs.chinaunix.net/forum/viewtopic.php?t=541234
另外,此书2005年有了第二版,目前尚无中译本面世。我就是对照着2nd-en勘误1st-cn的。
2, 《Linux内核原始码情景分析》上、下。毛德操、胡希明著,浙江大学出版社,上册¥80,下册¥70. 评说:
本书是基于2.4.0内核的,比较早,也没听说会出第二版。上册讲解内存管理、中断、异常和系统调用、进程控制、文件系统和传统Unix IPC;下册讲解socket、设备驱动、SMP和引导。关于这套书的评价褒贬不一,我个人认为其深度是同类著作中最优秀的。本书基于Intel IA32体系,由于厚度大,非常多体系上的知识都捎带讲解了,所以如果你想深入了解内核的工作机制而又不非常熟悉Intel CPU的体系构造,本书是最合适的。缺点是:版本较老,没有TCP/IP协议栈部分(他讲的socket只是Unix域协议的),图表太少,不适合初学者入门。更有就是对学生朋友来说,可能书价偏高,这样的话能考虑先买上册,因为上册是核心部分,下册一大部分都在讲具体PCI/ISA/USB设备的驱动。
翻译:没什么翻译,作者是国人,而且行文流畅。本人书桌上诸多计算机经典图书当中,这套是唯一又经典又无阅读障碍的。
www.linuxforum.net内核版好多朋友已把这书读到六七遍了,我非常惭愧,上册差不多读熟了,下册就SMP部分还看过──但这就花费了整整1年的时间,更有好多弄不懂的。这里顺便说明另外一个研究内核常见的误区:目标太庞大。要知道Linux内核(最新的2.6.13)bzip2压缩之后37M,解压缩之后244M,根本不是哪个人能够吃透的。即使是内核的核心研发团队中,恐怕也只Linus Torvalds、Alan Cox、David Miller、Ingo Molnar寥寥数人会有比较全方面的了解,其他人都是做自己专门的部分。 我自己来说,目前已决定放弃内存管理的全部(slab层、LRU、rbtree等)、文件系统部分、外设驱动部分,暂时也没打算弄IA32以外的其他体系的部分。
3, 《深入理解Linux内核》第二版。中国电力出版社。也是陈莉君译。此书是Linux内核黑客在推荐图书时的最佳选择。 评说:
此书C版的converse兄送了我一本第一版,因此就没买第二版,比较后悔。因此只就第一版说一说,第一版基于2.2,第二版2.4 。我见O’Reilly官方主页上说第三版的英文版将于2005年11月出版,也不知咱们何时才能见到。此书图表非常多,形象地给出了关键数据结构的定义,和《情景分析》相比,本书内容紧凑,不会一个问题讲解动辄上百页,有提纲挈领的功用,不过深度上要逊于《情景分析》。
4, 其他的几本书。市面上能见到的其他的Linux内核的图书,象《Linux设备驱动程式》、《Linux内核原始码完全注释》及新出的《Linux内核分析及编程》等。
《Linux设备驱动程式》第二版是基于2.4的,中文翻译不错,中国电力出版。这书强调动手实践,但他是讲解“设备驱动”的,不是最核心的东西,而且有些东西没硬件的话无法实践,可能更适合驱动研发的程式员吧,不太适合那些For fun and profit的人。此书有第三版英文版,东南大学出版社影印,讲解2.6的,行文流畅,讲解的面也比第二版更广泛,我读过其中关于同步和互斥、内存分配的部分,感觉非常不错。
《Linux内核原始码完全注释》(机械工业出版社)是同济大学的博士生赵炯的著作,讲解0.1Linux内核,我没买也没看,有看过的朋友说一说。
《Linux内核分析及编程》(电子工业出版社)是刚刚出版的,国人写的,讲解2.6.11 。非常多人说好,但有人说不够系统,我没买,不敢评说。
更有一本清华出的《Linux内核编程指南(第三版)》,原书应该是好书,不过翻译、排版十分糟烂,脱字跳行,根本没法看,我买了一本又扔掉了。
5, 其他资源。 TLDP(The Linux Documentation Project)有大量文件,其中不少是关于内核的,有些是在国外出版过的,象《Linux Kernel Interls》《The Linux Kernel》《Linux Kernel Module Programming Guide》等,作者都是亲身参加研发的人,著作较为可信。
Http://www.linuxforum.net
中国Linux论坛的内核版。该版是研究内核的中文Linux社区中水平最高的,有非常多专家级别的牛人,强烈推荐去学习一下(但建议不要问太过分简单的问题,人家脾气再好也会烦的^_^),他的置顶贴简直是个包罗万象的FAQ,精华区也有非常多资料。只可惜太过曲高和寡,人气不是非常旺。
6, 一本不是讲解Linux的书:《现代体系结构上的Unix系统:内核程式员的SMP和Caching技术》,人民邮电出版社2003版,定价¥39. 本书虽然不是讲解Linux,不过对所有Unix内核都是适用的,适合对SMP和CPU的Cache这些组成原理知识不是非常熟的朋友,而且是非常多国外牛人推荐的书。中文版翻译非常负责。
更有个非常重要的问题:怎样浏览内核原始码。有的朋友喜欢在视窗系统上工作,用Source Insight;有的在Linux,用Source Navigator;更有专门浏览原始码的软件,象lxr(Linux Cross Reference);更有用ctags/ectags/cscope等,这些都是非常优秀的软件。我个人用Vim + ctags浏览(参考了www.linuxforum.net内核版wheelz大侠的文件,)。
此外,前边已提到的一个重要的问题是:你研究内核的目的是什么, 研发? 乐趣?如果是研发,而且是国内做研发,把kernel API熟悉一下就差不太多了(你也知道国内的水平有多差),比方说copy_from_user()、kmalloc()函数等,kernel API在Internet上找得到,编译内核时也能用DocBook生成(具体请参考内核原始码包下的README文件);如果是研究,那就差别非常大了,需要下非常大的苦功:会用kmalloc()绝不说明你懂得Linux内核的虚存管理子系统,正如同会讲汉语不说明你懂中国文化相同。
说完了,发现前面讲的太罗嗦了,简化一下:
1, 动手编译内核
2, 精读《Linux内核设计和实现》
3, 上www.linuxforum.net内核版看置顶贴和精华区
此外就凭自己兴趣选择吧。
下面是一篇没写完的《Linux内核模块编程入门》,不补写了,将就着看吧。
albcamus 2005-10-13 02:41
写给Linux内核新手-关于Linux内核学习的误区
Linux内核模块编程入门
看到昨天有好几个问linux内核编程问题的帖子,不少是卡在了入门问题上,就整理一下入门的初步流程。针对2.6内核的Linux系统,需要你的机器上已安装了kernel-devel这个包,也就是编译模块所必须的东西:内核的头文件和一些Makefile。
一,Hello World程式:
#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif
#include ;
#include ;
#include ;
static int hello_init(void)
{
printk(KERN_ALERT "Hello, The fucking crazy world\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Bye, The fucking crazy world!\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("albcamus ;");
2.6内核的kbuild子系统跟2.4相比有本质的改动。我们下面尝试两种方式编译这个程式:
1, 你能在本目录下这样写一个Makefile
[Copy to clipboard] [ - ]CODE:obj-m := hell.o
clean:
rm -rf *.o .*.cmd *.ko *.mod.c .tmp_versions
然后用这样的命令行编译:
make -C /lib/modules/`uname -r`/build M=`pwd` modules
这时ls一下,就能看到生成了非常多文件,其中hello.ko就是我们需要的内核模块。
2, 专业点儿,Makefile这样写:
[Copy to clipboard] [ - ]CODE:obj-m := hello.o
KERNELBUILD := /lib/modules/`uname -r`/build
default:
make -C $(KERNELBUILD) M=$(shell pwd) modules
clean:
rm -rf *.o .*.cmd *.ko *.mod.c .tmp_versions
然后只要make一下就能了。
插入模块用insmod命令:
insmod ./hello.ko
这时候大家可能会问:为什么我的屏幕上没有见到输出?这个是console的日志记录级别和你printk消息时指定的级别(本例中指定为KERN_ALERT,为次高,仅次于KERN_EMERG)决定的。无论怎么,你能tail 或cat看看系统日志的最后几行,系统日志一般为/var/log/messages,或直接用dmesg命令,肯定能看到输出了。
二,头文件问题。
C程式员都知道,要使用某个外部的函数,应当#include某个头文件,这个头文件包含了那个函数的原型(prototype)。内核的头文件在include/下,其中include/asm是个符号链接,指向你所用内核的具体的体系结构目录,比方说我的系统是i386的,那么include/asm就指向include/asm-i386 。
内核编程中我们不能链接libc库,不能使用libc库中的函数,所以非常有些麻烦。一些重要的函数,象strcpy/strcmp/snprintf等,kernel也为我们实现并导出(export)了,而我们需要#include相关的头文件,在include/linux和include/asm中,你需要自己寻找你所要使用的函数在哪个头文件中声明,并将其#include进来。
写给Linux内核新手-关于Linux内核学习的误区
说点别的
1、楼主4K太屈材了,不过中国目前这个状况没法说。我原来去清华紫光面试,做AS400的售前/后支持「当时他们说有Unix基础就能,不必非常了解400」,底薪4K+提成,提成完全看销售业绩,估计非常大一部分工作是配合销售去把产品骗出去,技术性工作估计不多。如果销售情况好的话收入还是非常可观的,不过具他们内部人说没有销售挣得多。在国内许多大公司,一群本科是什么杂7杂8专业的,后来混了个“计算机”方面的“研究生”,啥都不懂成天混的人也都随便拿上5K+
2、牛人在中国会是什么下场?牛人就是象老牛相同多干活,还不一定有草吃。去年冬天我出差去昆明部署一个我们的软件,本来我只负责技术支持,职责就是按照文件把整个系统搭建起来。临走前研发人员和测试人员拍胸匍向我发誓程式完全没有问题了,我去到那里只要安装一下即可。结果到了那里,首先是客户系统被入侵而瘫痪,费了好大劲重建了系统恢复了数据库;接着发现程式有非常严重bug,花了整整一天时间我给他debug。
知道我最终的下场是什么吗?400块长途手机费不给报销,领导说按照规定每天只给报20。嗯,“按照规定”的话,发现被黑我就应该即时打110『没必要估计客户的面子』,然后叫合作伙伴的人来装系统(系统原来是他们装的),这样就省下200块打电话请示领导、联络客户领导的手机费;“按照规定”的话,我作为非研发人员和测试人员没义务给程式debug,当我发现程式不能正常运作的时候就应该打道回府,这样就又能省下200块了
我当时所在中国非常有名的一家软件上市公司「比红旗用友什么的大得多」,在这里我就不点名了
3、“到一家实力强劲的公司(如IBM,redflag)给人家打下手”?
IBM内部的中国研发人员,只能从老美那里拿到裁减版的API手册,非常多“牛人”的主要工作是汉化、debug、写文件和打包
redflag?以前原来有一个项目需要邮件系统,看了一下redflag的邮件服务器宣传还不错,联系了一下,跟一个什么产品经理谈了谈,结果是,为了拿到项目,他们完万能放弃linux平台把他移植到客户指定的Solaris上去,总之就是只要能中标,怎么都行!所以我看redflag需要的不是“打下手”的,需要的是能够拿到单子的sells