U-boot分析(1)

来源:互联网 发布:网络吞吐率 编辑:程序博客网 时间:2024/05/17 07:23

1. u-boot是一款功能十分强大的bootloader,分析其代码,获悉bootloader的基本写法。

 

2. sbc2410这块开发板为例分析,u-boot版本为2010.03

 

3. cpu相关部分

3.1 cpu在硬件上就是一个门阵列,是一个完全的逻辑器件,它提供了指令集,对cpu的控制就是靠对cpu发送相关指令实现的。这些指令是一连串的二进制码,将这些二进制码发送到cpu指令总线上就能控制cpubootloader就是这个二进制码序列,编译u-boot就是为了生成bootloader。生成后的bootloader文件会被写入flasheeprom等存储器中,cpu会在启动后自动加载运行bootloader中的二进制指令,从而启动。

3.2 指令序列存放在何处?又该如何存放?顺序如何?这些就要看lds文件,一段的格式分开存放这些数据和指令。

3.2.1 sbc2410开发板的cpus3c2410,属于arm 920t系列。对这个些列cpu的支持文件在cpu/arm920t下,里面有个u-boot.lds的文件。内容如下:

<cpu/arm920t/u-boot.lds>

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

OUTPUT_ARCH(arm)

ENTRY(_start)

SECTIONS

{

         . = 0x00000000;

         . = ALIGN(4);

         .text :

         {

                   cpu/arm920t/start.o       (.text)

                   *(.text)

         }

         . = ALIGN(4);

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

         . = ALIGN(4);

         .data : { *(.data) }

         . = ALIGN(4);

         .got : { *(.got) }

         . = .;

         __u_boot_cmd_start = .;

         .u_boot_cmd : { *(.u_boot_cmd) }

         __u_boot_cmd_end = .;

         . = ALIGN(4);

         __bss_start = .;

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

         _end = .;

}

网上有专门介绍这个lds文件格式的文档,这些知识是一定要掌握的,具体的就不多说了,看了文档自己就能全看明白了。大体上能看出,起始地址是0x00000000,依次向下有如下几个段.text .rodata .data .got .u_boot_cmd .bss (NOLOAD)

3.3  最前面的是text段,里面的代码是   {

                   cpu/arm920t/start.o       (.text)

                   *(.text)

         }

最先放的是cpu/arm920t/start.o  (.text),即cpu/arm920t/start.o文件的text段内容。这个文件是cpu/arm920t/start.S编译而得来的。

最先的一段

.globl _start

_start:      b       start_code

         ldr    pc, _undefined_instruction

         ldr    pc, _software_interrupt

         ldr    pc, _prefetch_abort

         ldr    pc, _data_abort

         ldr    pc, _not_used

         ldr    pc, _irq

         ldr    pc, _fiq

 

_undefined_instruction:  .word undefined_instruction

_software_interrupt:       .word software_interrupt

_prefetch_abort:     .word prefetch_abort

_data_abort:            .word data_abort

_not_used:                .word not_used

_irq:                   .word irq

_fiq:                    .word fiq

存放的第一个指令是一个跳转指令,后面是异常处理表,分别有相应的处理函数。

start_code:

        

         mrs  r0, cpsr

         bic    r0, r0, #0x1f

         orr    r0, r0, #0xd3

         msr  cpsr, r0

cpu工作在svc模式下

         bl      coloured_LED_init

         bl      red_LED_on

LED灯的控制,以方便程序调试,但是是空函数。

#if     defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK)

        

         ldr    r0, =_start

         ldr    r1, =0x0

         mov r2, #16

copyex:

         subs r2, r2, #1

         ldr    r3, [r0], #4

         str    r3, [r1], #4

         bne  copyex

#endif

将异常处理表复制到0x0000000处,前面看到这个表就是放在此处的,所以不需操作。

#ifdef CONFIG_S3C24X0

        

# if defined(CONFIG_S3C2400)

#  define pWTCON          0x15300000

#  define INTMSK   0x14400008    

#  define CLKDIVN 0x14800014    

#else

#  define pWTCON          0x53000000

#  define INTMSK   0x4A000008    

#  define INTSUBMSK    0x4A00001C

#  define CLKDIVN 0x4C000014    

# endif

通过宏定义了一些地址常量,具体这些寄存器的内容,需要看s3c2410手册才行。

         ldr    r0, =pWTCON

         mov r1, #0x0

         str    r1, [r0]

关闭watchdog功能,不然一到时间就cpu就复位了。

        

         mov r1, #0xffffffff

         ldr    r0, =INTMSK

         str    r1, [r0]

# if defined(CONFIG_S3C2410)

         ldr    r1, =0x3ff

         ldr    r0, =INTSUBMSK

         str    r1, [r0]

# endif

将所有的中断都mask掉,不响应

        

        

         ldr    r0, =CLKDIVN

         mov r1, #3

         str    r1, [r0]

#endif      

设置时钟分频,应该是cpu上某些部分使用不同的时钟频率。

 

 

stack_setup:

         ldr    r0, _TEXT_BASE                

         sub   r0, r0, #CONFIG_SYS_MALLOC_LEN       

         sub   r0, r0, #CONFIG_SYS_GBL_DATA_SIZE

#ifdef CONFIG_USE_IRQ

         sub   r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)

#endif

         sub   sp, r0, #12                

留出空间,设置sp栈指针,此时可以运行C程序了

clear_bss:

         ldr    r0, _bss_start          

         ldr    r1, _bss_end            

         mov r2, #0x00000000              

清空bss

clbss_l:str         r2, [r0]              

         add  r0, r0, #4

         cmp r0, r1

         ble    clbss_l

 

         ldr    pc, _start_armboot

pc指向_start_armboot,即跳转执行start_armboot

_start_armboot:      .word start_armboot


原文见:http://blog.sina.com.cn/s/blog_559f6ffc0100j7yq.html