首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

zImage内核镜像解压过程详解 02

zImage内核镜像解压过程详解 02

建立C程序运行需要的缓存
  这时r2是缓存的结束地址,r4是kernel的最后执行地址,r5是kernel境象文件的开始地址
  用文件misc.c的函数decompress_kernel(),解压内核于缓存结束的地方(r2地址之后)。
  可能大家看了上面的文字描述还是不清楚解压的动态过程。还是先用图表的方式描述下代码的搬运解压过程。然后再针对中间的一些关键过程阐述。
  假定zImage在内存中的初始地址为0x30008000(这个地址由bootloader决定,位置不固定)
  1、初始状态

.text

0x30008000开始,包含piggydata段(即压缩的内核段)

. got

?

. data

?

.bss

?

.stack

4K大小


  2、head.S调用misc.c中的decompress_kernel刚解压完内核后

.text

0x30008000开始,包含piggydata段(即压缩的内核段)

. got

?

. data

?

.bss

?

.stack

4K大小

解压函数所需缓冲区

64K大小

解压后的内核代码

小于4M


  3、此时会将head.S中的部分代码重定位

.text

0x30008000开始,包含piggydata段(即压缩的内核段)

. got

?

. data

?

.bss

?

.stack

4K大小

解压函数所需缓冲区

64K大小

解压后的内核代码

小于4M

head.S中的部分重定位代码代码

reloc_start


  .text
  0x30008000开始,包含piggydata段(即压缩的内核段)
  . got
  . data
  .bss
  .stack
  4K大小
  解压函数所需缓冲区
  64K大小
  解压后的内核代码
  小于4M
  head.S中的部分重定位代码代码
  reloc_start至reloc_end
  4、跳转到重定位后的reloc_start处,由reloc_start至reloc_end的代码复制解压后的内核代码到0x30008000处,并调用call_kernel跳转到0x30008000处执行。
  解压后的内核 0x30008000 开始
  在通过head.S了解了动态过程后,大家可能会有几个问题:
  问题1:zImage是如何知道自己最后的运行地址是0x30008000的?
  问题2:调用decompress_kernel函数时,其4个参数是什么值及物理含义?
  问题3:解压函数是如何确定代码中压缩内核位置的?
  先回答第1个问题
  这个地址的确定和Makefile和链接脚本有关,在arch/arm/Makefile文件中的
  textaddr-y := 0xC0008000 这个是内核启动的虚拟地址
  TEXTADDR := $(textaddr-y)
  在arch/arm/mach-s3c2410/Makefile.boot中
  zreladdr-y := 0x30008000 这个就是zImage的运行地址了
  在arch/arm/boot/Makefile文件中
返回列表