U-BOOT分析

來源:互聯網
上載者:User

1. u-boot是一款功能十分強大的bootloader,分析其代碼,獲悉bootloader的基本寫法。

2. 以sbc2410這塊開發板為例分析,u-boot版本為2010.03。

3. cpu相關部分

3.1 cpu在硬體上就是一個門陣列,是一個完全的邏輯器件,它提供了指令集,對cpu的控制就是靠對cpu發送相關指令實現的。這些指令是一連串的二進位碼,將這些二進位碼發送到cpu指令匯流排上就能控制cpu。bootloader就是這個二進位碼序列,編譯u-boot就是為了產生bootloader。產生後的bootloader檔案會被寫入flash,eeprom等儲存空間中,cpu會在啟動後自動載入運行bootloader中的二進位指令,從而啟動。

3.2 指令序列存放在何處?又該如何存放?順序如何?這些就要看lds檔案,一段的格式分開存放這些資料和指令。

3.2.1 sbc2410開發板的cpu是s3c2410,屬於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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.