




已阅读5页,还剩4页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Linux内核入门集步骤一:获取内核代码 这年头,Linux成了一个时髦词。自诩对电脑玩的精通的学生和IT人士们,没有哪个不在自己的电脑上安装一、两个Linux,并自觉赶上了时髦。然而,在Ubuntu或SUSE的论坛中,经常有这样的对话: “你学Linux学了这么久,都学到了什么?” “哦,我现在Linux的安装、升级、桌面美化都很熟练!你看我这是最新版的Ubuntu,桌面很漂亮吧!” “” Linux社区中有一句名言:如果你进入你的操作系统不知道该做什么,那最好还是关掉电脑,一定有更重要的事等着你去做。说真的,如果对 Linux命令不熟练,真的不能算是学过Linux。然而另一方面,Linux内核虽然是一般用户可学可不学的内容,但可以说却是Linux操作系统中最 好玩的部分。尤其对于开发者而言,Linux内核开发绝对是最理想的磨练场所。51CTO编辑一直认为,国外之所以IT技术大拿林立,和他们从小接触类 UNIX系统、把玩内核开发是脱不了关系的。 下面是Linux内核开发者Robert Love写的一篇入门文章,号称“包教会”,推荐对Linux内核开发感兴趣的学生、Linux爱好者、开发者以及系统管理员们一定不要错过。当然,虽然标题说是包教会,你可能需要一定的Linux命令以及C语言的基础。 以下是正文内容: Linux内核一直都被视为学习Linux最难的一块,相信大家也一定看过不少关于内核的文章,但扪心自问,你现在究竟掌握了多少?本文将从零开始介绍被视为高深的Linux内核,内容涉及内核源代码的下载,编译,安装,以及内核开发相关的内容。 如何获取Linux内核源代码 下载Linux内核当然要去官方网站了,网站提供了两种文件下载,一种是完整的Linux内核,另一种是内核增量补丁,它们都是tar归档压缩包。除非你有特别的原因需要使用旧版本的Linux内核,否则你应该总是升级到最新版本。 使用Git 由Linus领头的内核开发队伍从几年前就开始使用Git版本控制系统管理Linux内核了(参考阅读:什么是Git?),而Git项目本身也 是由Linus创建的,它和传统的CVS不一样,Git是分布式的,因此它的用法和工作流程很多开发人员可能会感到很陌生,但我强烈建议使用Git下载和 管理Linux内核源代码。 你可以使用下面的Git命令获取Linus内核代码树的最新“推送”版本: $ git clone git://pub/scm/linux/kernel/git/torvalds/linux-2.6.git 然后使用下面的命令将你的代码树与Linus的代码树最新状态同步: $ git pull 安装内核源代码 内核包有GNU zip(gzip)和bzip2格式。Bzip2是默认和首选格式,因为它的压缩比通常比gzip更好,bzip2格式的 Linux内核包一般采用linux-x.y.z.tar.bz2形式的文件名,这里的x.y.z是内核源代码的具体版本号,下载到源代码包后,解压和抽 取就很简单了,如果你下载的是bzip2包,运行: $ tar xvjf linux-x.y.z.tar.bz2 如果你下载的是gzip包,则运行: $ tar xvzf linux-x.y.z.tar.gz 无论执行上面哪一个命令,最后都会将源代码解压和抽取到linux-x.y.z目录下,如果你使用Git下载和管理内核源代码,你不需要下载tar包,只需要运行git clone命令,它就会自动下载和解压。 内核源代码通常都会安装到/usr/src/linux下,但在开发的时候最好不要使用这个源代码树,因为针对你的C库编译的内核版本通常也链接到这里的。 应用补丁 Linux内核开发人员会将自己的修改做成补丁与其它人员分享,而且补丁是增量的,增量补丁是从一个内核树移动到另一个内核树的有效方法,不用 下载完整的内核包就可以升级内核,不仅可节省带宽,也节省了内核升级时间,应用补丁之前先进入内核源代码树所在目录,然后运行: $ patch p1 .config $ make oldconfig 内核配置好后,使用下面的命令进行生成: $ make 和2.6以前的内核不一样,在生成内核前不再需要执行make dep命令了,依赖树会自动维护,也不需要再指定特定的生成类型,如bzImage,或独立生成模块,默认Makefile规则会自动处理好一切。 将干扰信息最小化 在生成过程中会遭到警告和错误的干扰。最小化干扰信息的一个诀窍是重定向make的输出,但仍然会看到一些警告和错误: $ make ./detritus 如果你想查看生成输出,你可以事后阅读这个文件,如果你完全不想看到任何输出,那么就重定向到/dev/null: $ make /dev/null 同时执行多个生成作业 Make命令提供了一个功能可以将生成过程拆分成多个平行的作业,这些作业可以独立运行,也可以并行运行,在多处理器系统上可以极大地提高生成速度,也提高了处理器利用率,因为生成大型源代码树会出现大量的I/O等待时间。 默认情况下,make只能拆分成一个作业,因为Makefiles常常会包含不正确的依赖信息,如果真是这样,多个并行执行的作业将会引起混乱,最终会导致生成过程失败,如果Makefiles中的依赖信息无误,那么完全可以拆分成多个作业执行,如: $ make jn 这里的n表示拆分的作业数量,通常按每个处理器拆分成1-2个作业,例如,在一个16核心的机器上 ,你可以运行: $ make -j32 /dev/null 使用distcc或ccache等优秀的工具也可以大大提高生成速度。 安装新内核 内核生成好之后,你需要安装它,如何安装于系统架构和引导加载程序有关,我们以x86架构,grub引导加载程序为例进行说明。 首先将arch/i386/boot/bzImage拷贝到/boot,重命名为vmlinuz- version,这里的version也是 版本号,然后编辑/boot/grub/grub.conf,为新内核添加相应的项目,如果是使用LILO引导装载程序,则修改/etc /lilo.conf文件,然后运行lilo。 模块的安装与系统架构无关,都是自动完成的,以root用户运行: % make modules_install 这个命令会将所有编译好的模块安装到/lib/modules下对应的子目录中。 生成过程会在源代码树根目录下创建一个System.map文件,它包含一个符号查找表,映射内核符号到它们的起始地址,在调试期间可以用它将内存地址转换成函数和变量名。 可能会遇到的问题 与普通用户空间的应用程序相比,Linux内核有多个特殊的属性,下面是我认为最重要的一些不同: 内核既不访问C库也不访问标准C头; 内核是用GNU C编码的; 内核缺少用户空间提供的内存保护; 内核不能容易地执行浮点运算; 内核有一个小型的固定大小的进程堆栈; 由于内核支持异步中断和SMP,因此同步和并发是内核主要担心的问题; 可移植性也很重要。 下面我们就逐个来了解一下这些问题,所有内核开发人员都必须记住它们。 无libc或标准头 和用户空间应用程序不一样,内核并没有链接到标准的C库,也没有链接到任何其它的库,这样设计的原因有很多,包括如先有鸡还是先有蛋的问题,但主要原因还是速度和内核大小,不要说完整的C库,就是它的一个子集也够大,内核太大只会导致效率低下。 不要担心,许多常用的libc函数都在内核中实现了,例如,常见的字符串操作函数就位于lib/string.c中,只需要包括它的头文件就可以了。 这里的头文件指的是内核源代码树中的头文件,内核也只能使用树内的头文件,基础文件位于源代码根目录的include/目录下,例如,头文件就位于include/linux/inotify.h。 与架构相关的头文件则位于arch/include/asm,例如,如果在x86架构下编译,与你 架构相关的文件就是arch/x86/include/asm,只需要在引用这些头的地方加上asm/前缀即可,如。 漏掉的大部分都是类似printf()这样的函数,内核不会使用printf(),但它提供了printk()函数,其表现绝不比 printf()差,printk()会拷贝格式化的字符串到内核日志缓冲区,syslog程序就是从这里读取信息的,其用法也和printf()类似: printk(Hello world! A string %s and an integer %dn, str, i); printf()和printk()之间最大的不同是,printk()允许你指定一个优先级标记,syslogd使用这个标记确定在哪里显示内核消息,下面是一个使用优先级标记的示例: printk(KERN_ERR this is an error!n); 注意在KERN_ERR和打印的消息之间没有逗号,这是故意这么设计的,优先级使用一个预定义的字符定义,在编译期间它与打印的信息是串联的。 GNU C 和许多Unix内核类似,Linux内核也是用C编写的,但也许会让人很意外,内核不是用严谨的ANSI C编写的,内核开发人员用的却是gcc(GNU编译器集,包含了编译内核和Linux C程序的C编译器)中的各种语言扩展。 内核开发人员同时使用了C语言的ISO C99和GNU C扩展,这些变化让Linux内核与gcc结合得更紧密,但最近又出现了一个编译 器 英特尔的C编译器 也对gcc的功能支持得相当好,因此也可以用它来编译Linux内核。最低支持的gcc版本是3.2,建议采用 gcc 4.4或更高的版本编译。使用ISO C99扩展也是可以的,因为C99是C语言的官方版本。 内联函数 C99和GNU C都支持内联函数,内联函数是直接插入到每个函数调用的位置的,消除了函数调用和返回的开销,允许进一步优化,因为编译器可以 同时优化调用者和被调用函数,但它也有缺点,代码大小会增加,因为函数的内容被直接复制到所调用者内部了,因此也会增加内存消耗和指令缓存空间。内核开发 人员一般在小型时间很关键的函数中才会使用内联函数。 定义函数时,使用static和inline关键字声明内联函数,例如: static inline void wolf(unsigned long tail_size) 函数必须先声明后使用,否则编译器就不能使函数内联,一般做法是将内联函数放在头文件中,因为它们被标记为static,不会创建输出函数,如果内联函数仅在一个文件中使用,可以放在该文件的顶部。 在内核中,与复杂的宏相比,出于安全和可读性方面考虑,内联函数是首选。 内联汇编 Gcc C编译器允许在C函数中嵌入汇编指令,asm()编译器指令用于内联汇编代码,例如,这个内联汇编指令执行x86处理器的rdtsc指令,返回时间戳寄存器(tsc)的值: unsigned int low, high; asm volatile(rdtsc : =a (low), =d (high); /* low and high now contain the lower and upper 32-bits of the 64-bit tsc */ Linux内核是用C和汇编语言混合编写的,与底层硬件相关的代码很多都是用汇编语言写的,剩下的大部分内核代码都是直接用C编写的。 分支注解 Gcc C编译器内置了一个指令优化条件分支,内核将这个打包成易于使用的宏 -likely()和unlikely()。 先看下面这样的if语句: if (error) /* . */ 将这个分支标记为非常不可能采用 /* we predict error is nearly always zero . */ if (unlikely(error) /* . */ 相反,将这个分支标记为非常可能采用 /* we predict success is nearly always nonzero . */ if (likely(success) /* . */ 当分支指令已经知道一个优先级,或你想在一种情况下优化另一种情况时应该使用上述指令,最重要的是,当分支正确标记时,这些指令会提升性能,但如果分支标记错误则会降低性能,在内核代码中,unlikely()要使用得更多,因为if语句倾向于表示一种特殊情况。 无内存保护 当用户空间的应用程序尝试一个非法的内存访问时,内核可以捕捉到错误,发送SIGSEGV信号,杀掉进程,如果内核尝试一个非法的内存访问时,结果就不受控制了,因为谁也无法去控制内核,这也是内核最主要的失误。 此外,内核内存也是不可分页的,因此你消耗的每个内存字节都比物理内存的一个字节要少。 不能(容易)使用浮点数 当用户空间进程使用浮点指令时,内核要负责处理从整型到浮点模式的转换。 与用户空间不一样,内核不能无缝支持浮点数,因为它自己不能轻易地捕捉到自己,在内核中使用浮点数需要手动保存和恢复浮点数寄存器,因此除非却有必要,否则尽量不要在内核中做浮点运算。 小型,固定大小的堆栈 用户空间可以静态分配许多不同的堆栈,包括巨型结构和千元数组,这个行为是合法的,因为用户空间有很大的堆栈,并可以动态增长。 内核堆栈不大也不是动态的,相反,它很小且是固定的,内核堆栈的精确大小根据架构有所不同,在x86上,堆栈大小是在编译时确定的,一般是 4KB或8KB,历史上,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 屋顶光伏租赁合同协议书
- 建筑材料工厂转让协议书
- 店铺合作股权分配协议书
- 固定车位安装柱子协议书
- 托管班暑期用工合同范本
- 服装代理销售协议书范本
- 监控及电脑采购合同范本
- 欧式城堡租赁协议书范本
- 调料代理合同协议书范本
- 刷脸支付招商合作协议书
- 2025年彩票技术管理员招聘笔试模拟题
- 迷彩九月+启航青春+课件-2025-2026学年高一上学期开学军训动员主题班会
- 2025年暑期教师研修心得-研修蓄力笃行致远
- 2025秋人教版初中数学九年级上册教学计划及进度表
- 2025年中国烟花爆竹协会烟花工艺师认证考试专项练习含答案
- 2025年政府会计准则制度实施能力考试(气象事业单位)高频错题及答案
- 2024年陕西事业单位联考A类综合应用能力试题及答案
- 河北省大厂回族自治县2025年上半年事业单位公开招聘教师岗试题含答案分析
- 人教版物理九年级全一册16.1《电压》听评课记录
- (2025年标准)被迫堕胎补偿协议书
- 咸阳赤壁市事业单位招聘笔试真题2024
评论
0/150
提交评论