zoukankan      html  css  js  c++  java
  • 从boot到bootstrap

    do_bootm函数及其所调用的函数,根据头部的定位地址(mkimage –a的参数)

    将zImage搬移到指定的内存处),根据头部的入口地址(mkimage –e的参数)

    获得head.o在内存中的地址,设置r0、r1、r2跳到此处执行。

    boot传入r0=0,r1=machine_ID,r2=taglist  (r0为0, r1为machine type, r2位参数列表的物理地址)

    在次过程中会开启Icache、Dcache,来加速开机过程

    程序中有一段称为 LC0的表,其中根据链接脚本确定了got段的起始和结束地址,bss段的起始和结束地址,栈的地址(比链接脚本中的指定的stack大于4),解压的内核存放于物理内存的起始地址。

    还有一个LC0标号记录了链接时的LC0标号地址,以及一个链接脚本中程序的链接起始地址_start

    如何计算一个程序的在物理内存中运行的起始地址:

    1、取运行是LC0的地址(PC加相对地址);设为r0

    2、取链接程序的起始地址_start;设为r5

    3、区链接是LC0标号的值;设为r1

    4、r0-r1+r5即为程序在物理内存中的起始地址

    注:一般将链接程序起始地址设为0,故_start=0,实际是unicore也是这么干的

    根据r0-r1修正got表的内容(即got表的中每一项+(ro-r1)),同时建立bss段。

    判定若将内核解压是否会覆盖掉自身:

    1、r5=r0-r1+r5  zImage在物理内存中的起始地址

    2、r2=sp+64K

    3、r4=解压存放地址

    4、r3=sp-r5

    5、若r4>r2显然不会覆盖,执行解压

    若r4+2r3显然不会覆盖,执行解压

    否则挂掉。

    在实际应用中出现了这样的问题:

    为加速测试音频,没有启动android,而只是挂载了ramdisk,alsa所需的库名、配置文件名(通过objdump、hexdump、strings都可以获得),但是做出的uImage大概4.5M,而image为9M多,现在指定的内核搬移到了40808000,而解压到的地址是400080000,结果40008000+9M>40808000,因此head及misc被冲掉,所以内核不能正常解压,修正的方法是改正kernel/arch/unicore/boot/Makefile下的LOADADDR,使得zImage在内存的地址>40008000+9M,例如师兄修正的41808000

     

    还有个问题,我们可以在将zImage制成uImage时将解压到的地址写入头部,这样boot可以将获取的信息放在合适的位置,感觉这样更好,但是实际上头部没有还有这个信息。

  • 相关阅读:
    C语言32个关键字详解
    C语言格式控制符
    c++关键字详解
    多码流简介
    Jtag管脚定义
    关于RGB信号的电平
    缩略语MSPS
    【转】松下18650的容量判别方法
    电信号在FR4材料中的传播速度
    dropout voltage
  • 原文地址:https://www.cnblogs.com/openix/p/2472034.html
Copyright © 2011-2022 走看看