S3C2440驱动开发(十二)

内核启动流程

 

内核启动分为两个阶段,内核引导阶段和内核启动阶段。内核引导阶段又可细分为,自解压搬运,内核启动前预处理。首先介绍自解压搬运流程,再介绍内核启动过程。

(一)内核引导阶段(自解压搬运)

前面章节已经介绍过bootloadert跳转到内核运行的过程,本节主要介绍内核自解压启动流程。

上一节介绍了zImage文件的生成过程,zImage是可执行文件格式,是由arch/arm/boot/compressed/vmlinux文件通过objcopy转化的。而arch/arm/boot/compressed/vmlinux则是由arch/arm/boot/compressed/vmlinux.lds , arch/arm/boot/compressed/head.o ,

arch/arm/boot/compressed/piggy.o,arch/arm/boot/compressed/misc.o这三个文件生成的。这三个文件是我们研究的重点。

zImage文件的起始地址由arch/arm/boot/compressed/vmlinux.lds决定,而vmlinux.lds是由同目录下的vmlinux.lds.in文件生成。

阅读这个文件之前需要了解下lds文件。Lds文件称为链接脚本,每个链接过程都由lds控制。主要作用是规定如何把输入文件中的section放到输出文件内,并控制输出文件内各部分在程序地址空间内的布局。目标文件的每个section至少包含两个信息: 名字和大小。

链接脚本由一系列命令组成, 每个命令由一个关键字(一般在其后紧跟相关参数)或一条对符号的赋值语句组成. 命令由分号‘;’分隔开。

文件名或格式名内如果包含分号’;'或其他分隔符, 则要用引号‘”’将名字全称引用起来. 无法处理含引号的文件名。/* */之间的是注释。

文件vmlinux.lds中Line10

OUTPUT_ARCH(arm)

命令OUTPUT_ARCH指定一个特定的输出机器架构。可以使用带-f选项的objdump程序查看一个目标文件的架构。

文件vmlinux.lds中Line11

ENTRY(_start)

程序第一个被执行的指令称之为入口点。命令ENTRY设置入口点,参数是一个符号名。

文件vmlinux.lds中Line19

  . = 0;

把定位器符号置为0。

Line20、23符号赋值,此处忽略不看。

Line24 *(.start)即对应arch/arm/boot/compressed/head.S中Line115

                   .section ".start", #alloc, #execinstr

Line33 *(.piggydata)对应arch/arm/boot/compressed/piggy.S中Line1

         .section .piggydata,#alloc

从这里我们可以知道zImage是从head.S中开始运行,内核压缩镜像放到了head.s和misc.c程序最后。

我们开始看arch/arm/boot/compressed/head.S文件。

Line121~124起延时功能。

Line130~131 保存bootloader传入的其中两个参数,硬件ID和参数指针

Line164~171

                   adr   r0, LC0

 ARM(               ldmia        r0, {r1, r2, r3, r4, r5, r6, ip, sp}        )

 THUMB(                   ldmia        r0, {r1, r2, r3, r4, r5, r6, ip}      )

 THUMB(                   ldr    sp, [r0, #28]                                 )

                   subs r0, r0, r1           @ calculate the delta offset

将LCO当前运行处的地址传入r0,即程序开始于0x30008000的地址。

接着将LCO符号处的数据保存到r1, r2, r3, r4, r5, r6, ip, sp这些寄存器中。值为链接时确定的地址,即开始于0的地址。

r0保存的是运行实时地址与编译地址的偏差。

Line302~309

LC0:          .word        LC0                     @ r1

                   .word        __bss_start               @ r2

                   .word        _end                            @ r3

                   .word        zreladdr            @ r4

                   .word        _start                          @ r5

                   .word        _got_start                 @ r6

                   .word        _got_end          @ ip

                   .word        user_stack+4096              @ sp

Line181~183

                   add  r5, r5, r0

                   add  r6, r6, r0

                   add  ip, ip, r0

Line193~195

                   add  r2, r2, r0

                   add  r3, r3, r0

                   add  sp, sp, r0

此处修正了r2,r3,r5,r6,ip,sp的值

Line200~204

1:               ldr    r1, [r6, #0]                 @ relocate entries in the GOT

                   add  r1, r1, r0           @ table.  This fixes up the

                   str    r1, [r6], #4                 @ C references.

                   cmp r6, ip

                   blo    1b

此处修正GOT表。GOT(Global Offset Table)表中每一项都是本运行模块要引用的一个全局变量或函数的地址。可以用GOT表来间接引用全局变量、函数,也可以把GOT表的首地址作为一个基准,用相对于该基准的偏移量来引用静态变量、静态函数。

Line220~226

not_relocated:         mov r0, #0

1:               str    r0, [r2], #4                 @ clear bss

                   str    r0, [r2], #4

                   str    r0, [r2], #4

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值