U-BOOT.dls学习

1 篇文章 0 订阅
1 篇文章 0 订阅

u-boot.lds 

     对于.lds文件,决定一个可执行程序的各个段的存储位置,以及入口地址,这也是链接定位的作用。这里以u-boot的lds为例说明uboot的链接过程。
首先看一下GNU官方网站上对.lds文件形式的完整描述:
SECTIONS {
...
secname start BLOCK(align) (NOLOAD) : AT ( ldadr )
  { contents } >region :phdr =fill
...
}
secname和contents是必须的,前者用来命名这个段,后者用来确定代码中的什么部分放在这个段,以下是对这个描述中的一些关键字的解释。
  1、secname:段名
  2、contents:决定哪些内容放在本段,可以是整个目标文件,也可以是目标文件中的某段(代码段、数据段等)
  3、start:是段的重定位地址,本段连接(运行)的地址,如果代码中有位置无关指令,程序运行时这个段必须放在这个地址上。start可以用任意一种描述地址的符号来描述。
  4、AT(ldadr):定义本段存储(加载)的地址,如果不使用这个选项,则加载地址等于运行地址,通过这个选项可
以控制各段分别保存于输出文件中不同的位置。
例:
/* nand.lds */
SECTIONS {
firtst 0x00000000 : { head.o init.o }
second 0x30000000 : AT(4096) { main.o }
}
   
     以上,head.o放在0x00000000地址开始处,init.o放在head.o后面,他们的运行地址也是0x00000000,即连接和存储地址相同(没有AT指定);main.o放在4096(0x1000,是AT指定的,存储地址)开始处,但它的运行地址在0x30000000,运行之前需要从0x1000(加载地址处)复制到0x30000000(运行地址处),此过程也就需要读取 flash,把程序拷贝到相应位置才能运行。这就是存储地址和运行地址的不同,称为加载时域和运行时域,可以在.lds连接脚本文件中分别指定。
    编写好的.lds文件,在用arm-linux-ld连接命令时带-Tfilename来调用执行,如
    arm-linux-ld –Tnand.lds x.o y.o –o xy.o。也用-Ttext参数直接指定连接地址,如
    arm-linux-ld –Ttext 0x30000000 x.o y.o –o xy.o。
    既然程序有了两种地址,就涉及到一些跳转指令的区别。
ARM汇编中,常有两种跳转方法:b跳转指令、ldr指令向PC赋值。
要特别注意这两条指令的意思:
(1)       b step:b跳转指令是相对跳转,依赖当前PC的值,偏移量是通过该指令本身的    bit[23:0]算出来的,这使得使用b指令的程序不依赖于要跳到的代码的位置,只看指令本身。
(2)       ldr pc, =step :该指令是一个伪指令编译后会生成以下代码:
        ldr pc, 0x30008000
        <0x30008000>
                        step
    是从内存中的某个位置(step)读出数据并赋给PC,同样依赖当前PC的值,但是偏移量是step的连接地址(运行时的地址),所以可以用它实现从Flash到RAM的程序跳转。
 (3) 此外,有必要回味一下adr伪指令,U-boot中那段relocate代码就是通过adr实现当前程序是在RAM中还是flash中:
              relocate:                                   /* 把U-Boot重新定位到RAM */
              adr r0, _start                       /* r0是代码的当前位置 */
/* adr伪指令,汇编器自动通过当前PC的值算出这条指令中“_start"的值,执行到_start时PC的值放到r0中:
当此段在flash中执行时r0 = _start = 0;当此段在RAM中执行时_start = _TEXT_BASE(在board/smdk2410/config.mk中指定的值为0x33F80000,即u-boot在把代码拷贝到RAM中去执行的代码段的开始) */
    ldr r1, _TEXT_BASE                       /* 测试判断是从Flash启动,还是RAM */
/* 此句执行的结果r1始终是0x33FF80000,因为此值是链接指定的 */
    cmp r0, r1                                    /* 比较r0和r1,调试的时候不要执行重定位 */
    结合u-boot.lds谈谈连接脚本。

//;三个分别指定在缺省、大端、小端情况下的输出可执行文件格式,这里都指定输出格式是elf32,小端和arm体系结构。

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")

 

OUTPUT_ARCH(arm)

/*  指定可执行映像文件的起始段的段名是_start */

ENTRY(_start)

SECTIONS

{

/* 指定可执行image文件的全局入口点,通常这个地址都放在ROM(flash)0x0位置。必须使编译器知道这个地址,通常都是修改此处来完成 */

       . = 0x00000000;   /* 起始地址为0x00000000  */

 

;地址进行4字节对齐调整。

       . = ALIGN(4);

       .text :

       {

/*  代码段第一部分代码*/

              cpu/arm920t/start.o     (.text)

/*  代码段第二部分,这段由自己添加,由于在编译连接时发现,lowlevel_init.o代码段总是被连接在4kB之后,导致start.s执行到该段代码时,总是无法找到这段代码(注明:从nandflash启动才会存在这个问题)。*/

              board/samsung/smdk2410/lowlevel_init.o(.text)

              board/samsung/smdk2410/nand_read.o(.text)

/*其余代码段*/

              *(.text)

       }

 

       . = ALIGN(4);

/*  只读数据段 ,所有的只读数据段都放在这个位置*/

       .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }

 

       . = ALIGN(4);

/* 可读写数据段,所有的可读写数据段都放在这里 */

       .data : { *(.data) }

 

       . = ALIGN(4);

/*指定got段, got段式是uboot自定义的一个段, 非标准段*/

       .got : { *(.got) }

 

       . = .;

       __u_boot_cmd_start = .; /*把__u_boot_cmd_start赋值为当前位置, 即起始位置*/
    .u_boot_cmd : { *(.u_boot_cmd) }  /*  u_boot_cmd段,所有的u-boot命令相关的定义都放在这个位置,因为每个命令定义等长,所以只要以__u_boot_cmd_start为起始地址 进行查找就可以很快查找到某一个命令的定义,并依据定义的命令指针调用相应的函数进行处理用户的任务*/
    __u_boot_cmd_end = .;     /* u_boot_cmd段结束位置,由此可以看出,这段空间的长度并没有严格限制,用户可以添加一些u-boot的命令,最终都会在连接是存放在这个位置。*/   . = ALIGN(4);

 

/*把__bss_start赋值为当前位置,即bss段的开始位置*/

       __bss_start = .;

/*指定bss段,这里NOLOAD的意思是这段不需装载,仅在执行域中才会有这段*/

       .bss (NOLOAD) : { *(.bss) . = ALIGN(4); }

/*把_end赋值为当前位置,即bss段的结束位置*/

       _end = .;

}

 

说明1:标准应用程序包括 3 类标准段空间:.text 运行代段;.data 全局变量等具有初始值的数据空间;.bss暂态变量,堆栈等数据空间;

说明 2:.rodata,.got,.u_boot_cmd 等段空间由程序员设计需要而自行定义的段空间;

 

 

/board/samsung/smdk2410/config.mk 文件中定义了

#

# SMDK2410 has 1 bank of 64 MB DRAM

#

# 3000'0000 to 3400'0000

#

# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000

# optionally with a ramdisk at 3080'0000

#

# we load ourself to 33F8'0000

#

# download area is 3300'0000

#

 

 

TEXT_BASE = 0x33F80000

 

在顶层配置文件config.mk中154定义了CPPFLAGS 变量,其中指定了程序的链接基址为      TEXT_BASE

    CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS) -D__KERNEL__

    ifneq ($(TEXT_BASE),)

    CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE)

    Endif

 

 

下面翻译下:

#SMDK2410 每个bank有 64 MB DRAM

#3000'0000到3400'0000

#Linux的内核,预计将在3000'8000,进入3000'8000
#选择一个虚拟磁盘时3080'0000

#我们载入我们自己来33F8'0000

#下载区3300'0000

下面再来看下编译连接后的的system.map文件

33f80000 T _start   //看到了吧,这就是链接基地址,由编译器指定的TEXT_BASE

33f80000 t $a

33f80020 t $d

33f80020 t _undefined_instruction

33f80024 t _software_interrupt

33f80028 t _prefetch_abort

33f8002c t _data_abort

33f80030 t _not_used

33f80034 t _irq

33f80038 t _fiq

33f80040 t _TEXT_BASE

33f80044 T _armboot_start

33f80048 T _bss_start

33f8004c T _bss_end

33f80050 t $a

33f80050 t start_code

33f800b8 t relocate

33f800d8 t copy_loop

33f800ec t nand_boot

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CREATE TEMPORARY FUNCTION UUIDUDF AS 'com.haierubic.bigdata.commons.udf.UUIDUDF' . . . . . . . . . . . . . . . . . > USING JAR 'oss://datalake-01.cn-beijing.oss-dls.aliyuncs.com/config/bigdata-hiveudf-2.1-jar-with-dependencies.jar'; Error: Error while compiling statement: FAILED: HiveAccessControlException Permission denied: user [hdop_upbrain] does not have [TEMPUDFADMIN] privilege on [global=uuidudf] (state=42000,code=40000) 0: jdbc:hive2://10.204.11.45:10000> CREATE FUNCTION UUIDUDF AS 'com.haierubic.bigdata.commons.udf.UUIDUDF' . . . . . . . . . . . . . . . . . > USING JAR 'oss://datalake-01.cn-beijing.oss-dls.aliyuncs.com/config/bigdata-hiveudf-2.1-jar-with-dependencies.jar'; INFO : Compiling command(queryId=hive_20230602122812_92858e15-5136-4e7d-9f51-3020f864aef2): CREATE FUNCTION UUIDUDF AS 'com.haierubic.bigdata.commons.udf.UUIDUDF' USING JAR 'oss://datalake-01.cn-beijing.oss-dls.aliyuncs.com/config/bigdata-hiveudf-2.1-jar-with-dependencies.jar' INFO : Concurrency mode is disabled, not creating a lock manager INFO : Semantic Analysis Completed (retrial = false) INFO : Returning Hive schema: Schema(fieldSchemas:null, properties:null) INFO : Completed compiling command(queryId=hive_20230602122812_92858e15-5136-4e7d-9f51-3020f864aef2); Time taken: 0.067 seconds INFO : Concurrency mode is disabled, not creating a lock manager INFO : Executing command(queryId=hive_20230602122812_92858e15-5136-4e7d-9f51-3020f864aef2): CREATE FUNCTION UUIDUDF AS 'com.haierubic.bigdata.commons.udf.UUIDUDF' USING JAR 'oss://datalake-01.cn-beijing.oss-dls.aliyuncs.com/config/bigdata-hiveudf-2.1-jar-with-dependencies.jar' INFO : Starting task [Stage-0:FUNC] in serial mode INFO : Added [/tmp/b11e4544-4a21-4dcf-87c5-fff8d91021e9_resources/bigdata-hiveudf-2.1-jar-with-dependencies.jar] to class path INFO : Added resources: [oss://datalake-01.cn-beijing.oss-dls.aliyuncs.com/config/bigdata-hiveudf-2.1-jar-with-dependencies.jar] INFO : Completed executing command(queryId=hive_20230602122812_92858e15-5136-4e7d-9f51-3020f864aef2); Time taken: 0.789 seconds INFO : OK INFO : Concurrency mode is disabled, not creating a lock manager No rows affected (0.881 seconds)
06-03

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值