u-boot的linux内核映像加载,Linux内核映像的生成过程

在各种各样使用Linux的计算机系统中,系统启动的早期阶段,通常都会有这样一个环节,

boot loader程序将内核映像加载到内存中,然后跳转到映像的起始位置开始执行。

接下来,内核就跑起来了。

那么,这个内核映像到底是个什么东东呢。本文就来简单介绍一下Linux内核映像的生成过程。

不当之处,尽请指正。

(一)  编译内核源码得到原始的内核目标文件kernel.o

这其实也就是真正意义上的内核了。系统中实际运行着的内核,其实就是他了。

这是一个elf格式的目标文件。

这个目标文件的入口代码在head.S中。例如,对于arm而言,就是arch\arm\kernel\head.S。

head.S执行到最后,会调用start_kernel(位于init/main.c中),从而进入C代码的世界。

内核目标文件的文件名,在不同架构的makefile中叫法可能不尽相同。我们这里就叫他 kernel.o 好了。

不同架构下的具体文件名,参见arch\xxx\boot\compressed\Makefile

另外,我们下文中所使用的文件名,也可能与makefile中的命名不一致。

不是不想一致,而是不同架构makefile中的命名确实不尽相同。

因此,我们这里为了表达的方便,就重新统一命名啦。

好了,kernel.o虽然是真正的内核,但他不是一下子就能运行起来的。就像火箭的发射需要发射架一样。

kernel.o要想跑起来,也需要再搭几个支架。

接下来的事情,就是一步步地在搭这个架子。

(二)  用objcopy工具给 kernel.o 减肥,得到kernel.bin

经过objcopy处理(其实就是二进制化)后,得到只剩下纯代码与数据的文件kernel.bin(raw binary格式)。

注意,kernel.bin已经不是elf文件了。他里面只有纯粹的指令与数据。

只所以这样做,是因为启动阶段的系统,软件环境很简陋,没有代码来分析elf文件的结构。

要加载一个程序,就是将他拷到内存中某个位置,然后跳到该位置执行。

因此,程序必须经过精心的链接,再去除所有不需要的信息,只留下纯粹的指令与数据。

要将一个elf文件二进制化,通过命令“objcopy -O binary  src_file  dst_file”即可。

(三)  用gzip压缩 kernel.bin 得到 piggy.gz

(四)  创建piggy.o用于包含piggy.gz文件的全部数据

piggy.o是一个elf文件,他内部包含了piggy.gz文件的全部数据。

piggy.o的目的,就是为了将piggy.gz作为数据与内核映像的其他部分进行链接。

在arm下,通过对arch\xxx\boot\compressed\piggy.S文件的编译,实现了piggy.o的创建。

在i386下,通过arch\i386\boot\compressed\vmlinux.scr链接脚本以及

arch\i386\boot\compressed\Makefile中类似如下的依赖关系,直接链接得到了piggy.o

$(obj)/piggy.o: $(src)/vmlinux.scr $(obj)/piggy.gz

(五)  将piggy.o及其他东东链接成vmlinux

将head.o、misc.o、piggy.o 链接成vmlinux。

对于arm来说,除了head.o、misc.o,可能还会将其他一些用到的东东链接进去。

(六)  生成最终的内核映像文件

a) 对于arm来说,步骤如下:

用objcopy工具给 vmlinux 减肥,得到zImage

vmlinux是elf文件,经过objcopy处理后,得到只剩下代码与数据的文件zImage(raw binary格式)。

注意,zImage已经不是elf文件了。

b) 对于x86来说,步骤与arm略有不同。

用objcopy工具给 vmlinux 减肥,得到vmlinux.bin(raw binary格式)。

再将bootsect(raw binary格式) 、setup(raw binary格式)与vmlinux.bin拼接到vmlinux.bin前面,得到bzImage。

其中,bootsect对应于arch\i386\boot\bootsect.S,setup对应于arch\i386\boot\setup.S。

这两个文件有什么用呢?

(1)  bootsect.S

其实是用于写到软盘的0扇区中(512字节),用于从软盘启动Linux内核。在2.6的内核中,这个文件已经不起作用了。

因此,2.6的内核中如果跑到他,他就简单打印一点错误信息,告诉用户需要由boot loader加载内核。

然后让用户按任意键重启。

而boot loader(例如,grub)在加载内核后,并没有跳转到内核映像起始位置执行,而是跳过了前面的512字节,即跳过了bootsect.S的内容。

(2)  setup.S

一般来说,如果是从arm u-boot环境启动。u-boot会将单板基本硬件信息放到一个特定位置,然后内核可以由此获取硬件信息。

而对于pc机来说,则是由setup.S来获取(通过bios)基本硬件信息,放到合适的位置,然后内核再由此获取硬件信息。

如果安装内核的话,新编译的bzImage将被拷贝到类似/boot/vmlinuz-2.6.18-194.el5这样的路径,后者的路径则有可能同时再被更新到/boot/vmlinuz软链接中。这样一来,/boot/vmlinuz总是指向系统中最新安装的内核。

原文:http://blog.csdn.net/crazycoder8848/article/details/19156503

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值