Linux 2.6 内核编译及过程分析

来源:互联网 发布:java wear 编辑:程序博客网 时间:2024/05/01 17:43

 

看学习Linux内核的知识,首先需要学习Linux内核的编译及引导的过程。

本文通过对Linux的2.6内核进行编译为例,介绍Linux内核的编译过程,并对内核的构建过程进行细致的分析。

1.自己手动编译Linux内核 

该例使用的Fedora13,通过使用git工具下载内核,读者也可以自己手动下载内核家压缩后使用

1. yum install git git-core fakeroot ncurses-devel

2. git clone http://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git

3. cd workspace dir

如果读者直接下载解压缩可以省略前三步,解压缩后进入src下即可。

4. make clean

//步骤4和步骤5对以往的历史进行清理

5. make mrproper

6. cp /boot/config-$(uanme -r) .config

//如果读者为了省略配置内核的工作,可以将当前系统的config文件复制过来

7. make menuconfig and select load the copied .config file

//并在make menuconfig中选择加载复制过来的config文件

8. (make rpm) get error when use this

8. make bzImage

//步骤8和步骤9可以用命令make all来代替,这在2.6.15后可以使用,该命令首先编译生成vmlinux,然后

//压缩生成bzImage,并编译相关的modules

9. make modules

10. make modules_install

//该命令用来安装内核模块,该命令首先在/lib/modules/中创建一个以内核发行号为名称的目录

//;然后将步骤9中编译,生成的内核模块复制到该新建目录中。

11.make install

//使用make install命令来安装编译生成的新内核,该命令调用了内核目录中的install.sh。详细命令为 src/arch/i386/boot/install.sh $版本号 arch/i386/boot/bzImage System.map "" 该命令将8.9生成的bzImage和System.map复制到/boot目录下,并依次改名为vmlinuz-版本号,System.map-版本号,并设置vmlinuz和system连接的对象。然后调用脚本/sbin/installkernel根据在内核配置,编译阶段生成的内核模块modules以及模块依赖关系/li/b/modules/版本号/modules.dep生成引导过程使用的临时根文件系统initrd。最后修改/boot/grub/grub.conf文件,添加新的引导菜单。

12.reboot //重启选择即可

2.分析内核镜像的构建过程

1.构建内核镜像vmlinux

根据在内核配置阶段生成的.config将系统核心和built-in的系统组件进行编译,最后根据指定的链接脚本arch/i386/kernel/vmLinux.lds生成虽然src/vmLinux文件。

1)C和汇编源文件被编译成ELF可重定位object文件(.o),相当于windows的.obj文件,其中一部分按照逻辑分组用ar命令打包成压缩文件(即静态链接库文件.a)。 

(ar命令用来创建、修改库,也可以从库中提出单个模块,.a文件就是一系列.o文件的压缩包。) 

2)调用ld命令将以上的.o和.a文件链接成一个静态的non-stripped的ELF格式的在80386 32位平台上运行的可执行文件vmlinux。 

(ld命令把一定量的目标文件和档案文件链接起来, 重定位他们的数据,non-stripped表示没有去除符号表,可以使用函数、变量名访问,

用于debug过程;而strip之后只能通过地址访问。vmlinux就是未压缩的Linux内核。) 

3)调用nm vmlinux 指令剔除不相关和不感兴趣的符号并创建内核符号表。 

(例 如nm /boot/vmlinux-2.4.7-10 > System.map。内核符号表是内核变量地址和变量名的对应关系,每次编译时产生新的,

内核通过地址识别符号,而用户需要使用符号名编码和链接,例如 内核日志记录后台程序,通过System.map便于对内核的调试。) 

2.对vmlinux进行瘦身并进行压缩

1)通过cojcopy对vmlinux进行瘦身,去掉.note段和.comment段,并转化为raw binrary格式。

2)通过gzip对vmlinux.bin进行压缩。

3)将压缩文件vmlinux.bin.gz包装成elf格式存放到 /arch/i386/boot/compressed/piggy.o。

4)把压缩程序head.S 和misc.c文件编译成head.o和misc.o(misc.c包含了zlib算法的解压缩代码c语言的实现,head.s中包含的汇编代码用于为

调用解压缩程序设置调用参数和解压缩过程使用的堆,栈,然后调用misc中的解压缩代码将压缩的内核解压并移动到合适的地方)

3.构建包含解压缩代码的vminux镜像

使用连接器ld将包含压缩的系统核心的文件piggy.o与head.o,misc.o链接生成新的文件boot/compressed/vmLinux.

4.对新生成的vmlinux再次瘦身

通过objcopy删除.note和.comment段,转化为raw binary格式,生成arch/i386/boot/vmLinux.bin.

5.构建内核镜像bzImage

利用内核镜像构建工具build将bootsect,setup,vmLinux.bin三个文件依次放到bzImage文件中去。bootsect是一个引导扇区(详情见下一篇介绍linux内核引导的文章),一般

情况下是512字节,最后两个字节为55AA.然后填充setup部分,补足512字节。之后为vmlinux.bin。按照setup,vmLinux实际所占扇区数更改bootsect中相应的指示位置,使得

bzImage[497] = setup所占扇区属,bzImage[500,501]= vmLinux.bin所占扇区数。

原创粉丝点击