powerpc uboot链接脚本大改造

http://blog.csdn.net/skyflying2012/article/details/48846833

 

在做完了linux由arm处理器核移植到ppc处理器核的工作后,还需要进行uboot的移植,之前对uboot的分析文章都是基于arm平台,感兴趣的朋友可以看看,链接如下:
http://blog.csdn.net/column/details/uboot-note.html
借这次ppc移植工作,也学习了ppc uboot的相关知识,顺道写几篇文章记录下。
工作背景是公司处理器由arm处理器核cortex A8换为ppc处理器核ppc460s,现在处于FPGA仿真验证阶段,SOC的外设控制器都没有变化.

uboot版本号:2014.04
平台:powerpc460s

根据之前arm版本uboot的移植经验,一次完整的uboot移植我觉得可以分为3步:
(1)根据需求,对uboot进行配置,链接等方面的修改,加入必须的板级支持函数(先为空函数即可),保证uboot可以编译链接通过。
(2)由start.s开始,按照uboot启动流程对调用到的各个关键函数进行功能调试。保证uboot正常启动进入命令行。
(3)对各个模块驱动单独调试。

因此我修改boards.cfg,修改配置文件,确定代码段首地址,内存首地址等基本要素。期望能够直接编过。
但是看了ppc460s处理器的链接脚本后,我觉得问题比我想象中要复杂一点。
根据我的实际需求需要对ppc的链接脚本进行改造,其实就是将uboot镜像中各个section进行重新布局。今天趁十一假期,来记录下对ppc uboot链接脚本的改造过程。
首先来分析下原版uboot针对ppc460s处理器各个section的布局,ppc460s属于ppc4xx系列,因此链接脚本是arch/powerpc/cpu/ppc4xx/u-boot.lds。结合arch/powerpc/cpu/ppc4xx/start.S等启动代码,我画出了ppc4xx系列处理器uboot段布局图如下。
这里写图片描述
bootpg和resetvec位于4G地址空间顶端的4k空间,其余段则位于指定的地址。虚线表明了处理器上电后执行流程。
这里就需要简单说明下ppc4xx系列处理器的一点特性,ppc4xx系列处理器很大的一个特点是MMU常开,上电即开启。
上电后ppc4xx有一个shadow TLB将地址空间最顶端的4k进行映射,具体映射到哪里,这就要看处理器内部逻辑如何填该TLB,以及外部总线的地址仲裁如何布局物理地址空间,这点询问SOC的IC设计人员就可以知道。
初上电的ppc4xx处理器只能访问顶端4K空间,并且上电取指地址是0xfffffffc,因此在针对ppc4xx系列处理器,bootloader的设计一般就是0xfffffffc处为跳转指令,跳转至4k起始地址执行,在该4k代码中对需要进行访问的地址空间进行TLB映射,保证之后主代码所在物理地址的映射,最后跳转到主代码段执行。
可以看出uboot的设计就是遵循这个特点,上电首先执行jump _start_440,跳转到4k起点执行,初始化TLB之后jump _start,进入代码段执行。
因此uboot完全可以作为ppc4xx处理器的bootloader来使用,上电直接执行uboot。

但是对于我们公司处理器,却产生了一些问题,问题如下:
(1)公司处理器逻辑将顶端4k空间映射到片内64k的ROM中,该ROM存放公司开发的bootloader,uboot太大放不进去
(2)uboot实际相当于一个二级bootloader,由公司一级bootloader加载uboot启动,uboot进行必要的配置和参数准备,再去启动kernel
(3)公司处理器的需求是uboot直接运行在内存中,仅仅起一个承上启下的作用,为kernel传参。
从公司处理器的需求来看,所需要的uboot并不是一个完整的bootloader,而仅仅是在内存中运行,为kernel准备参数,加载启动kernel就可以。这样uboot的段布局就需要改造一下。

根据这个需求,对uboot的链接布局我提出来的改进方案如下:
(1)顶部跳转和地址空间映射的任务由一级bootloader完成,uboot仅需要直接在内存中运行即可,因此考虑将bootpg以及resetvec去掉。
(2)原代码段执行是由_start_440–>_start跳转来切入的,现在需要手动指定uboot入口为_start。

针对第一条改进方案,起初考虑过保留bootpg,但是由于bootpg在地址空间的顶端4k,根据实际的处理器地址空间分布,我的代码段启动地址CONFIG_SYS_TEXT_BASE是在内存的0x80e80000,需要注意的是这个地址是一个虚拟地址,因为公司一级bootloader中已经完成了地址空间的映射,都是平映射。但是这样uboot最终链接生成u-boot.bin时,就会有1G大小,这是因为最高位置的段bootpg和最低位置的段text之间间隔了将近1G,生成镜像时这之间的空隙是需要预留出来的,来保证加载是能够将各个段加载正确位置。

这里就想到一个问题,难道别的ppc4xx处理器,如果使用uboot作为一级bootloader,text段在内存中,而内存地址距离地址空间顶端很远,编译出来的u-boot.bin就会非常大吗?
查看别的ppc4xx处理器的相关代码,发现解决方法是在4k代码中将内存映射到接近顶端4k的地址,同时修改CONFIG_SYS_TEXT_BASE为该地址。这样编译链接出来的u-boot.bin就不大了。

因此我上面的考虑,有一个很重要的前提是我在4k代码中为需要使用的地址空间做了平映射。公司处理器的一级bootloader中的确是这样做的。

这样想来,对于我的uboot,bootpg段还有一种解决方法,是保留bootpg,修改其中TLB映射,将内存代码段地址映射到接近顶端4k的位置,并且修改CONFIG_SYS_TEXT_BASE。
但是由于一级bootloader的存在,已经将跳转以及TLB映射工作做完,所以uboot并不需要4k代码,并且uboot本身不算很大,平映射完全满足需求,为了移植简单快捷,我还是采用将bootpg等段删掉的方法。

因此我将arch/powerpc/cpu/ppc4xx/u-boot.lds中如下代码注掉。

<code class="hljs vala has-numbering"><span class="hljs-preprocessor">#if 0 </span>
<span class="hljs-preprocessor">#ifndef CONFIG_SPL</span>
<span class="hljs-preprocessor">#ifdef CONFIG_440</span>
  .bootpg<span class="hljs-constant"> RESET_VECTOR_ADDRESS </span>- <span class="hljs-number">0xffc</span> :
  {
    arch/powerpc/cpu/ppc4xx/start.o (.bootpg)

    <span class="hljs-comment">/*
     * PPC440 board need a board specific object with the
     * TLB definitions. This needs to get included right after
     * start.o, since the first shadow TLB only covers 4k
     * of address space.
     */</span>
<span class="hljs-preprocessor">#ifdef CONFIG_INIT_TLB</span>
   <span class="hljs-constant"> CONFIG_INIT_TLB </span>(.bootpg)
<span class="hljs-preprocessor">#else</span>
    CONFIG_BOARDDIR/init.o  (.bootpg)
<span class="hljs-preprocessor">#endif</span>
  } :text = <span class="hljs-number">0xffff</span>
<span class="hljs-preprocessor">#endif</span>

  .resetvec<span class="hljs-constant"> RESET_VECTOR_ADDRESS </span>:
  {
    KEEP(*(.resetvec))
  } :text = <span class="hljs-number">0xffff</span>

  . =<span class="hljs-constant"> RESET_VECTOR_ADDRESS </span>+ <span class="hljs-number">0x4</span>;

  <span class="hljs-comment">/*
   * Make sure that the bss segment isn't linked at 0x0, otherwise its
   * address won't be updated during relocation fixups.  Note that
   * this is a temporary fix.  Code to dynamically the fixup the bss
   * location will be added in the future.  When the bss relocation
   * fixup code is present this workaround should be removed.
   */</span>
<span class="hljs-preprocessor">#if (RESET_VECTOR_ADDRESS == 0xfffffffc)</span>
  . |= <span class="hljs-number">0x10</span>;
<span class="hljs-preprocessor">#endif</span>
<span class="hljs-preprocessor">#endif /* CONFIG_SPL */</span>
<span class="hljs-preprocessor">#endif</span>
  __bss_start = .;
  .bss (NOLOAD)       :
  {
   *(.bss*)
   *(.sbss*)
   *(COMMON)
  } :bss

  . = ALIGN(<span class="hljs-number">4</span>);
  __bss_end = . ;
 <span class="hljs-constant"> PROVIDE </span>(end = .);</code><ul style="FILTER: ; ZOOM: 1" class="pre-numbering"><li>1</li></ul>

将u-boot.lds中的bootpg resetvec段定义注释掉。这里需要注意的一点是bss段。在最后再进行讨论。
修改链接脚本后,还需要将start.S中bootpg段代码以及resetvec.S中resetvec段代码也注释掉,这里就不列了。

到这里,整个bootpg resetvec段就去掉了,原来u-boot的执行是按照由上电入口地址0xfffffffc开始,一路跳转进入_start,进入text代码段执行的。
现在没有了bootpg resetvec,u-boot.bin的入口地址就需要指定下了。
链接器ld可以通过参数-Ttext指定text段起始地址,通过参数-e指定程序入口地址。在uboot的Makefile中,如下:

<code class="hljs mel has-numbering">MKIMAGEFLAGS_u-boot.kwb = -n <span class="hljs-variable">$(</span>srctree)/<span class="hljs-variable">$(</span>CONFIG_SYS_KWD_CONFIG:<span class="hljs-string">"%"</span>=<span class="hljs-variable">%)</span> \
    -T kwbimage -a <span class="hljs-variable">$(</span>CONFIG_SYS_TEXT_BASE) -e <span class="hljs-variable">$(</span>CONFIG_SYS_TEXT_BASE)</code><ul style="FILTER: ; ZOOM: 1" class="pre-numbering"><li>1</li></ul>

默认是uboot入口地址与代码段起始地址一致。但是根据上面u-boot段分布图可以看出,text段真正的入口地址是在_start,前面0x2100大小的代码是版本字符串以及异常向量表。
因此需要指定下uboot的入口地址。我的修改方法是在u-boot.lds中加入如下代码。

<code class="hljs scss has-numbering"><span class="hljs-function">ENTRY(_start)</span></code><ul style="FILTER: ; ZOOM: 1" class="pre-numbering"><li>1</li></ul>

指定入口地址在_start,_start地址是text段起始地址加上0x2100.
对链接脚本进行如上修改之后,编译通过uboot还需要一些板级支持函数,对于powerpc平台,如initsdram board_early_init_r等,可以先为空函数,待功能调试时再完善,最终uboot编译通过。

通过readelf查看生成的u-boot,如下:

<code class="hljs sql has-numbering">zk@server2:~/u-boot$ powerpc-linux-readelf -h u-boot
ELF Header:
  Magic:   7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, big endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           PowerPC
  Version:                           0x1
  Entry point address:               0x80e82100
  <span class="hljs-operator"><span class="hljs-keyword">Start</span> <span class="hljs-keyword">of</span> program headers:          <span class="hljs-number">52</span> (bytes <span class="hljs-keyword">into</span> file)
  <span class="hljs-keyword">Start</span> <span class="hljs-keyword">of</span> <span class="hljs-keyword">section</span> headers:          <span class="hljs-number">600904</span> (bytes <span class="hljs-keyword">into</span> file)
  Flags:                             <span class="hljs-number">0x18000</span>, relocatable, relocatable-lib
  <span class="hljs-keyword">Size</span> <span class="hljs-keyword">of</span> this header:               <span class="hljs-number">52</span> (bytes)
  <span class="hljs-keyword">Size</span> <span class="hljs-keyword">of</span> program headers:           <span class="hljs-number">32</span> (bytes)
  <span class="hljs-keyword">Number</span> <span class="hljs-keyword">of</span> program headers:         <span class="hljs-number">2</span>
  <span class="hljs-keyword">Size</span> <span class="hljs-keyword">of</span> <span class="hljs-keyword">section</span> headers:           <span class="hljs-number">40</span> (bytes)
  <span class="hljs-keyword">Number</span> <span class="hljs-keyword">of</span> <span class="hljs-keyword">section</span> headers:         <span class="hljs-number">20</span>
  <span class="hljs-keyword">Section</span> header string <span class="hljs-keyword">table</span> index: <span class="hljs-number">17</span></span></code><ul style="FILTER: ; ZOOM: 1" class="pre-numbering"><li>1</li></ul>

可以看出,入口地址正是我指定的_start地址,再查看各个段的分布,如下:

<code class="hljs avrasm has-numbering">zk@server2:~/u-boot$ powerpc-linux-readelf -S u-boot
There are <span class="hljs-number">20</span> section headers, starting at offset <span class="hljs-number">0x92b48</span>:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ <span class="hljs-number">0</span>]                   NULL            <span class="hljs-number">00000000</span> <span class="hljs-number">000000</span> <span class="hljs-number">000000</span> <span class="hljs-number">00</span>      <span class="hljs-number">0</span>   <span class="hljs-number">0</span>  <span class="hljs-number">0</span>
  [ <span class="hljs-number">1</span>] <span class="hljs-preprocessor">.text</span>             PROGBITS        <span class="hljs-number">80e80000</span> <span class="hljs-number">000074</span> <span class="hljs-number">017510</span> <span class="hljs-number">00</span>  AX  <span class="hljs-number">0</span>   <span class="hljs-number">0</span>  <span class="hljs-number">4</span>
  [ <span class="hljs-number">2</span>] <span class="hljs-preprocessor">.rodata</span>           PROGBITS        <span class="hljs-number">80e97510</span> <span class="hljs-number">017584</span> <span class="hljs-number">005717</span> <span class="hljs-number">00</span>   A  <span class="hljs-number">0</span>   <span class="hljs-number">0</span>  <span class="hljs-number">4</span>
  [ <span class="hljs-number">3</span>] <span class="hljs-preprocessor">.reloc</span>            PROGBITS        <span class="hljs-number">80e9</span>cd00 <span class="hljs-number">01</span>cd74 <span class="hljs-number">0014</span>b8 <span class="hljs-number">04</span> WAX  <span class="hljs-number">0</span>   <span class="hljs-number">0</span>  <span class="hljs-number">4</span>
  [ <span class="hljs-number">4</span>] <span class="hljs-preprocessor">.data</span>             PROGBITS        <span class="hljs-number">80e9</span>e1b8 <span class="hljs-number">01e22</span>c <span class="hljs-number">001120</span> <span class="hljs-number">00</span>  WA  <span class="hljs-number">0</span>   <span class="hljs-number">0</span>  <span class="hljs-number">4</span>
  [ <span class="hljs-number">5</span>] <span class="hljs-preprocessor">.u</span>_boot_list      PROGBITS        <span class="hljs-number">80e9</span>f2d8 <span class="hljs-number">01</span>f34c <span class="hljs-number">0004</span>f8 <span class="hljs-number">00</span>  WA  <span class="hljs-number">0</span>   <span class="hljs-number">0</span>  <span class="hljs-number">4</span>
  [ <span class="hljs-number">6</span>] <span class="hljs-preprocessor">.bss</span>              NOBITS          <span class="hljs-number">80e9</span>f800 <span class="hljs-number">01</span>f844 <span class="hljs-number">002798</span> <span class="hljs-number">00</span>  WA  <span class="hljs-number">0</span>   <span class="hljs-number">0</span>  <span class="hljs-number">4</span>
  [ <span class="hljs-number">7</span>] <span class="hljs-preprocessor">.debug</span>_line       PROGBITS        <span class="hljs-number">00000000</span> <span class="hljs-number">01</span>f844 <span class="hljs-number">00</span>c63c <span class="hljs-number">00</span>      <span class="hljs-number">0</span>   <span class="hljs-number">0</span>  <span class="hljs-number">1</span>
  [ <span class="hljs-number">8</span>] <span class="hljs-preprocessor">.debug</span>_info       PROGBITS        <span class="hljs-number">00000000</span> <span class="hljs-number">02</span>be80 <span class="hljs-number">0338e8</span> <span class="hljs-number">00</span>      <span class="hljs-number">0</span>   <span class="hljs-number">0</span>  <span class="hljs-number">1</span>
  [ <span class="hljs-number">9</span>] <span class="hljs-preprocessor">.debug</span>_abbrev     PROGBITS        <span class="hljs-number">00000000</span> <span class="hljs-number">05</span>f768 <span class="hljs-number">00</span>b114 <span class="hljs-number">00</span>      <span class="hljs-number">0</span>   <span class="hljs-number">0</span>  <span class="hljs-number">1</span>
  [<span class="hljs-number">10</span>] <span class="hljs-preprocessor">.debug</span>_aranges    PROGBITS        <span class="hljs-number">00000000</span> <span class="hljs-number">06</span>a880 <span class="hljs-number">0018</span>d8 <span class="hljs-number">00</span>      <span class="hljs-number">0</span>   <span class="hljs-number">0</span>  <span class="hljs-number">8</span>
  [<span class="hljs-number">11</span>] <span class="hljs-preprocessor">.comment</span>          PROGBITS        <span class="hljs-number">00000000</span> <span class="hljs-number">06</span>c158 <span class="hljs-number">000027</span> <span class="hljs-number">01</span>  MS  <span class="hljs-number">0</span>   <span class="hljs-number">0</span>  <span class="hljs-number">1</span>
  [<span class="hljs-number">12</span>] <span class="hljs-preprocessor">.gnu</span><span class="hljs-preprocessor">.attributes</span>   LOOS+ffffff5    <span class="hljs-number">00000000</span> <span class="hljs-number">06</span>c17f <span class="hljs-number">000012</span> <span class="hljs-number">00</span>      <span class="hljs-number">0</span>   <span class="hljs-number">0</span>  <span class="hljs-number">1</span>
  [<span class="hljs-number">13</span>] <span class="hljs-preprocessor">.debug</span>_frame      PROGBITS        <span class="hljs-number">00000000</span> <span class="hljs-number">06</span>c194 <span class="hljs-number">0046</span>dc <span class="hljs-number">00</span>      <span class="hljs-number">0</span>   <span class="hljs-number">0</span>  <span class="hljs-number">4</span>
  [<span class="hljs-number">14</span>] <span class="hljs-preprocessor">.debug</span>_str        PROGBITS        <span class="hljs-number">00000000</span> <span class="hljs-number">070870</span> <span class="hljs-number">0063</span>f9 <span class="hljs-number">01</span>  MS  <span class="hljs-number">0</span>   <span class="hljs-number">0</span>  <span class="hljs-number">1</span>
  [<span class="hljs-number">15</span>] <span class="hljs-preprocessor">.debug</span>_loc        PROGBITS        <span class="hljs-number">00000000</span> <span class="hljs-number">076</span>c69 <span class="hljs-number">01934</span>f <span class="hljs-number">00</span>      <span class="hljs-number">0</span>   <span class="hljs-number">0</span>  <span class="hljs-number">1</span>
  [<span class="hljs-number">16</span>] <span class="hljs-preprocessor">.debug</span>_ranges     PROGBITS        <span class="hljs-number">00000000</span> <span class="hljs-number">08</span>ffb8 <span class="hljs-number">002</span>ac8 <span class="hljs-number">00</span>      <span class="hljs-number">0</span>   <span class="hljs-number">0</span>  <span class="hljs-number">8</span>
  [<span class="hljs-number">17</span>] <span class="hljs-preprocessor">.shstrtab</span>         STRTAB          <span class="hljs-number">00000000</span> <span class="hljs-number">092</span>a80 <span class="hljs-number">0000</span>c7 <span class="hljs-number">00</span>      <span class="hljs-number">0</span>   <span class="hljs-number">0</span>  <span class="hljs-number">1</span>
  [<span class="hljs-number">18</span>] <span class="hljs-preprocessor">.symtab</span>           SYMTAB          <span class="hljs-number">00000000</span> <span class="hljs-number">092e68</span> <span class="hljs-number">004080</span> <span class="hljs-number">10</span>     <span class="hljs-number">19</span> <span class="hljs-number">533</span>  <span class="hljs-number">4</span>
  [<span class="hljs-number">19</span>] <span class="hljs-preprocessor">.strtab</span>           STRTAB          <span class="hljs-number">00000000</span> <span class="hljs-number">096</span>ee8 <span class="hljs-number">0031</span>b5 <span class="hljs-number">00</span>      <span class="hljs-number">0</span>   <span class="hljs-number">0</span>  <span class="hljs-number">1</span>
Key to Flags:
  W (write), A (alloc), <span class="hljs-built_in">X</span> (execute), M (merge), S (strings)
  I (info), L (link order), G (group), T (TLS), E (exclude), <span class="hljs-built_in">x</span> (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)</code><ul style="FILTER: ; ZOOM: 1" class="pre-numbering"><li>1</li></ul>

代码段起始于0x80e80000.都符合了我的要求。
这样针对公司处理器的需求,对u-boot链接脚本的改造就完成了。

总结下,在改造过程中我觉得有2个地方值得思考。
1 bss段的几个疑问
在修改u-boot.lds去掉bootpg resetvec时,我注意到bss定义位于resetvec之上,resetvec已经到了地址空间的顶点,难道bss段超出了4G
后来实际编译我才发现,根据u-boot.lds中的定义,resetvec位于0xfffffffc时,bss位于(0xfffffffc+4)| 0x10的位置,地址就是0x10.如果resetvec定义在其他位置,则bss就在resetvec之上了。
根据编译生成的elf文件u-boot,获取到各个段的大小,与u-boot.bin比较,如下:

<code class="hljs ruby has-numbering">zk<span class="hljs-variable">@server2</span><span class="hljs-symbol">:~/u-boot</span><span class="hljs-variable">$ </span>size u-boot
   text    data     bss     dec     hex filename
 <span class="hljs-number">123103</span>    <span class="hljs-number">5656</span>   <span class="hljs-number">10136</span>  <span class="hljs-number">138895</span>   <span class="hljs-number">21</span>e8f u-boot
zk<span class="hljs-variable">@server2</span><span class="hljs-symbol">:~/u-boot</span><span class="hljs-variable">$ </span>ls -lh u-boot.bin
-rwxr-xr-x <span class="hljs-number">1</span> zk git <span class="hljs-number">126</span>k <span class="hljs-number">2015</span>-<span class="hljs-number">10</span>-<span class="hljs-number">01</span> <span class="hljs-number">15</span><span class="hljs-symbol">:</span><span class="hljs-number">22</span> u-boot.bin
</code><ul style="FILTER: ; ZOOM: 1" class="pre-numbering"><li>1</li></ul>

计算下可以发现,u-boot.bin基本等于text与data段之和,问题来了,bss段哪里去了

在网上查找资料才知道,原来在最终的程序镜像中,是没有bss段。
为什么去掉bss段,想来想去,我的理解是bss段中包括了未初始化以及初始化为0的全局变量和静态变量,该段的数据全部为0,但是占据空间大,为了减小镜像尺寸,才在objcopy生成镜像时将bss段删掉。
而根据uboot代码可以知道,对于uboot这样的裸编程序来说,在其启动过程中会开辟bss段,并对bss段进行清空,来保证其中数据全部为0.
这样就不会影响后续的全局变量和静态变量的使用了。

那么我的疑问又来了,在其开辟和清空bss段的过程中,是如何知道bss段的地址范围的。

这个问题想来倒是也好解答,在编译链接过程中,我们就可以确定下来bss段的起止地址,在u-boot.lds中用__bss_start和__bss_end来表示了。
并且该起止地址记录到了u-boot这个elf文件的段表中,也就是上面readelf看到的段表列表的结果,
最终生成u-boot.bin时去掉了bss,也的确是应该去掉,占据空间大还全部为0,完全可以在程序运行时再根据__bss_start和__bss_end来分配清空就可以。

总结下,uboot中bss段的生成过程可以分为如下步骤:
(1)链接脚本中定义bss段地址范围__bss_start __bss_end。
(2)编译链接elf时,根据链接脚本确定下__bss_start __bss_end的绝对地址,记录在elf文件的段表中。
(3)elf objcopy生成u-boot.bin时,去掉bss段。
(4)加载u-boot.bin启动运行,根据__bss_start __bss_end开辟bss段,并全部清空为0。
(5)后续运行代码中访问未初始化和初始化为0的全局变量以及静态变量则会访问到bss段中。

一句话,bss段在uboot生成镜像时删掉,在运行时动态分配清空,从而达到减小镜像尺寸的目的。

2 程序起始地址与入口地址的关系
从这次修改ppc u-boot连接脚本就可以看出来,程序起始地址与入口地址不是一个概念,完全可以不相等。由于u-boot.lds中将text段的定义放在了最开始的位置,所以text段的起始地址就是整个uboot镜像的起始地址了,代码段在最前面,这也是最常用的链接方式。程序入口地址可以通过链接器的参数-e来指定。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值