Arm linux启动分析(5)
2013-12-19 20:53
344 查看
二、U-boot链接脚本的介绍
1
uboot的链接脚本的内容及分析如下
OUTPUT_FORMAT("elf32-littlearm",
"elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start) //指定启动时的函数入口地址,_start在每个CPU的start.S中定义
//真正的启动运行地址段由TEXT_BASE宏定义在编译时由config.mk中定义
SECTIONS
{
.
= 0; //指定系统启动从偏移地址 0开始
.
= ALIGN(4); //地址进行4字节对其调整,确保低 2bit地址线为 0
.text : //定义.text段空间
{
cpu/sep4020/start.o (.text) //指定 start.o目标文件首先从.text段分配
*(.text) //后续.text段内容的分配
}
.
= ALIGN(4); //.text段处理后,进行4字节地址对其调整,然后分配.rodata段空间
.rodata
: { *(.rodata) }
.
= ALIGN(4); //4字节地址调整,然后分配.data段空间
.data
: { *(.data) }
.
= ALIGN(4); //4字节地址调整,然后分配.got段空间
.got
: { *(.got) }
__u_boot_cmd_start
= .; //定义.u_boot_cmd的段空间,
.u_boot_cmd
: { *(.u_boot_cmd) } //并且__u_boot_cmd_start符号指向段空间开始
__u_boot_cmd_end
= .; //__u_boot_cmd_end符号指向该段空间结束
armboot_end_data
= .; //
armboot_end_data符号指向之前所有分配完段的结束,
//后续将开始.bss段的分配
.
= ALIGN(4); //地址 4字节调整,开始分配.bss段空间
__bss_start
= .; //.bss段空间开始地址
.bss
: { *(.bss) }
_end
= .; //.bss段空间结束地址
}
说明1:标准应用程序包括 3 类标准段空间:.text 运行代段;.data 全局变量等具有初始值的数据空间;.bss暂态变量,堆栈等数据空间;
说明 2:.rodata,.got,.u_boot_cmd 等段空间由程序员设计需要而自行定义的段空间;
说明 3:本PPT采用 ARM720T
CPU 进行分析,其指令字长为 4字节,所以地址调整为 4 字节;
2
U-boot起始地址的指定
(1)在配置文件config.mk中154定义了CPPFLAGS 变量,其中指定了程序的链接基址为 TEXT_BASE
CPPFLAGS
:= $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS) -D__KERNEL__
ifneq
($(TEXT_BASE),)
CPPFLAGS
+= -DTEXT_BASE=$(TEXT_BASE)
Endif
(2)在其后又在172行CFLAGS 包含了CPPFLAGS变量
CFLAGS
:= $(CPPFLAGS) -Wall -Wstrict-prototypes
(3)然后在主Makefile中将config.mk进来了,这样其中的大部分变量都在编译过程中有固定的值了
#
load other configuration
include
$(TOPDIR)/config.mk
(4)在生成elf可执行文件u-boot的命令中就指定了链接标志LDFLAGS
$(obj)u-boot: depend
$(SUBDIRS) $(OBJS) $(LIBBOARD) $(LIBS)
$(LDSCRIPT)
cd
$(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS)
\
--start-group
$(__LIBS) --end-group $(PLATFORM_LIBS)
-Map
u-boot.map -o u-boot
三、U-boot的相关代码分析
1、cpu/sep4020/start.S启动分析
.globl _start
_start:
b reset //复位向量
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 //快速中断向量
_TEXT_BASE: //程序在SDRAM中运行的起始地址,即链接的起始地址
.word TEXT_BASE //
TEXT_BASE是链接时候的起始地址,在/board/prochip/UB4020/config.mk中定义的
.globl _armboot_start
_armboot_start: //程序运行起始地址,实际上是FLASH中程序的起始运行地址
.word _start
.globl _bss_start
_bss_start: //bss段的起始链接地址
.word __bss_start
.globl _bss_end
_bss_end: //bss段的链接结束地址
.word _end
reset://复位启动子程序
mrs r0,cpsr //设置 CPU为 SVC32模式
bic r0,r0,#0x1f
orr r0,r0,#0x13
msr cpsr,r0
ldr r0,
_TEXT_BASE//配置SVC模式的堆栈空间(在sdram中)
sub r0,
r0, #CFG_MALLOC_LEN
sub r0,
r0, #CFG_GBL_DATA_SIZE
#ifdef CONFIG_USE_IRQ
sub r0,
r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp,
r0, #12
#ifdef CONFIG_USE_IRQ
mov R4,
#0xD2 //切换 CPU为 IRQ模式
msr cpsr,
R4
ldr r0,
_TEXT_BASE //配置IRQ模式的堆栈空间(在sdram中)
sub r0,
r0, #CFG_MALLOC_LEN
sub r0,
r0, #CFG_GBL_DATA_SIZE
sub r0,
r0, #(CONFIG_STACKSIZE_FIQ)
sub sp,
r0, #12
。。。。。。。。。。其他模式配置堆栈省略。。。。。。。。。。。。。
mov R4,
#0xD3 //关闭系统的中断
msr cpsr,
R4
bl cpu_init_crit
cpu_init_crit://cpu的初始化
ldr r0,
=0x10001004
ldr r1,
=0x400B
str r1,
[r0]
ldr r0,
=0x10001014
ldr r1,
=0x1
str r1,
[r0]
ldr r0,
=0x10001004
ldr r1,
=0xC00B
str r1,
[r0]
ldr r0,
=0x1000100C
ldr r1,
=0xFFFFFFFF
str r1,
[r0]
#if 1
ldr r0,
=0x1000500C
ldr r1,
=0x83
str r1,
[r0]
ldr r0,
=0x10005004
ldr r1,
=0x0
str r1,
[r0]
ldr r0,
=0x10005000
ldr r1,
=0x2F
str r1,
[r0]
ldr r0,
=0x1000500C
ldr r1,
=0x3
str r1,
[r0]
#endif
mov pc,
lr
bl lowlevel_init
.globl
lowlevel_init
lowlevel_init:
ldr r4, =EMI_CSECONF
ldr r5, =0x8ca6a6a1
str r5, [
r4 ]
ldr r4, =EMI_SDCONF1
ldr r5, =0x1E184177
str r5, [
r4 ]
ldr r4, =EMI_SDCONF2
ldr r5, =0x80001860
str r5, [
r4 ]
remap:
mov r0, pc
add r0, r0, #0x20000000
add r0, r0, #0x08
mov pc, r0
mov r0, r0
mov r0, r0
mov r0, r0
mov r0, r0
ldr r4, =0x11000020
ldr r5, =0xb //remap到sdram中
str r5, [
r4 ]
ldr r0, = 0
ldr r1, _bss_start
ldr r2, _bss_end
bss_init:
str r0, [r1]
add r1,r1,#4
cmp r1,r2
blt bss_init
#ifndef
CONFIG_SKIP_RELOCATE_UBOOT
relocate:
adr r0,
_start
ldr r1,
_TEXT_BASE
cmp r0,
r1
beq vector_copy //如果相等则说明已经在sdram中,这时候只需要搬运中断向量表
ldr r2,
_armboot_start
ldr r3,
_bss_start
sub r2,
r3, r2
add r2,
r0, r2
copy_loop: //正真的代码搬运过程
ldmia r0!,
{r3-r10}
stmia r1!,
{r3-r10}
cmp r0,
r2
ble copy_loop
vector_copy:
ldr r0,
_TEXT_BASE
add r2,
r0, #128
ldr r1,
=0x30000000
vector_copy_loop://搬运中断向量表的循环
ldmia r0!,
{r3-r10}
stmia r1!,
{r3-r10}
cmp r0,
r2
ble vector_copy_loop
#endif
mrs R4,
cpsr
bic R4,
R4, #0x80
msr cpsr,
R4
ldr pc,
_start_armboot
_start_armboot: .word
start_armboot
1
uboot的链接脚本的内容及分析如下
OUTPUT_FORMAT("elf32-littlearm",
"elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start) //指定启动时的函数入口地址,_start在每个CPU的start.S中定义
//真正的启动运行地址段由TEXT_BASE宏定义在编译时由config.mk中定义
SECTIONS
{
.
= 0; //指定系统启动从偏移地址 0开始
.
= ALIGN(4); //地址进行4字节对其调整,确保低 2bit地址线为 0
.text : //定义.text段空间
{
cpu/sep4020/start.o (.text) //指定 start.o目标文件首先从.text段分配
*(.text) //后续.text段内容的分配
}
.
= ALIGN(4); //.text段处理后,进行4字节地址对其调整,然后分配.rodata段空间
.rodata
: { *(.rodata) }
.
= ALIGN(4); //4字节地址调整,然后分配.data段空间
.data
: { *(.data) }
.
= ALIGN(4); //4字节地址调整,然后分配.got段空间
.got
: { *(.got) }
__u_boot_cmd_start
= .; //定义.u_boot_cmd的段空间,
.u_boot_cmd
: { *(.u_boot_cmd) } //并且__u_boot_cmd_start符号指向段空间开始
__u_boot_cmd_end
= .; //__u_boot_cmd_end符号指向该段空间结束
armboot_end_data
= .; //
armboot_end_data符号指向之前所有分配完段的结束,
//后续将开始.bss段的分配
.
= ALIGN(4); //地址 4字节调整,开始分配.bss段空间
__bss_start
= .; //.bss段空间开始地址
.bss
: { *(.bss) }
_end
= .; //.bss段空间结束地址
}
说明1:标准应用程序包括 3 类标准段空间:.text 运行代段;.data 全局变量等具有初始值的数据空间;.bss暂态变量,堆栈等数据空间;
说明 2:.rodata,.got,.u_boot_cmd 等段空间由程序员设计需要而自行定义的段空间;
说明 3:本PPT采用 ARM720T
CPU 进行分析,其指令字长为 4字节,所以地址调整为 4 字节;
2
U-boot起始地址的指定
(1)在配置文件config.mk中154定义了CPPFLAGS 变量,其中指定了程序的链接基址为 TEXT_BASE
CPPFLAGS
:= $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS) -D__KERNEL__
ifneq
($(TEXT_BASE),)
CPPFLAGS
+= -DTEXT_BASE=$(TEXT_BASE)
Endif
(2)在其后又在172行CFLAGS 包含了CPPFLAGS变量
CFLAGS
:= $(CPPFLAGS) -Wall -Wstrict-prototypes
(3)然后在主Makefile中将config.mk进来了,这样其中的大部分变量都在编译过程中有固定的值了
#
load other configuration
include
$(TOPDIR)/config.mk
(4)在生成elf可执行文件u-boot的命令中就指定了链接标志LDFLAGS
$(obj)u-boot: depend
$(SUBDIRS) $(OBJS) $(LIBBOARD) $(LIBS)
$(LDSCRIPT)
cd
$(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS)
\
--start-group
$(__LIBS) --end-group $(PLATFORM_LIBS)
-Map
u-boot.map -o u-boot
三、U-boot的相关代码分析
1、cpu/sep4020/start.S启动分析
.globl _start
_start:
b reset //复位向量
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 //快速中断向量
_TEXT_BASE: //程序在SDRAM中运行的起始地址,即链接的起始地址
.word TEXT_BASE //
TEXT_BASE是链接时候的起始地址,在/board/prochip/UB4020/config.mk中定义的
.globl _armboot_start
_armboot_start: //程序运行起始地址,实际上是FLASH中程序的起始运行地址
.word _start
.globl _bss_start
_bss_start: //bss段的起始链接地址
.word __bss_start
.globl _bss_end
_bss_end: //bss段的链接结束地址
.word _end
reset://复位启动子程序
mrs r0,cpsr //设置 CPU为 SVC32模式
bic r0,r0,#0x1f
orr r0,r0,#0x13
msr cpsr,r0
ldr r0,
_TEXT_BASE//配置SVC模式的堆栈空间(在sdram中)
sub r0,
r0, #CFG_MALLOC_LEN
sub r0,
r0, #CFG_GBL_DATA_SIZE
#ifdef CONFIG_USE_IRQ
sub r0,
r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp,
r0, #12
#ifdef CONFIG_USE_IRQ
mov R4,
#0xD2 //切换 CPU为 IRQ模式
msr cpsr,
R4
ldr r0,
_TEXT_BASE //配置IRQ模式的堆栈空间(在sdram中)
sub r0,
r0, #CFG_MALLOC_LEN
sub r0,
r0, #CFG_GBL_DATA_SIZE
sub r0,
r0, #(CONFIG_STACKSIZE_FIQ)
sub sp,
r0, #12
。。。。。。。。。。其他模式配置堆栈省略。。。。。。。。。。。。。
mov R4,
#0xD3 //关闭系统的中断
msr cpsr,
R4
bl cpu_init_crit
cpu_init_crit://cpu的初始化
ldr r0,
=0x10001004
ldr r1,
=0x400B
str r1,
[r0]
ldr r0,
=0x10001014
ldr r1,
=0x1
str r1,
[r0]
ldr r0,
=0x10001004
ldr r1,
=0xC00B
str r1,
[r0]
ldr r0,
=0x1000100C
ldr r1,
=0xFFFFFFFF
str r1,
[r0]
#if 1
ldr r0,
=0x1000500C
ldr r1,
=0x83
str r1,
[r0]
ldr r0,
=0x10005004
ldr r1,
=0x0
str r1,
[r0]
ldr r0,
=0x10005000
ldr r1,
=0x2F
str r1,
[r0]
ldr r0,
=0x1000500C
ldr r1,
=0x3
str r1,
[r0]
#endif
mov pc,
lr
bl lowlevel_init
.globl
lowlevel_init
lowlevel_init:
ldr r4, =EMI_CSECONF
ldr r5, =0x8ca6a6a1
str r5, [
r4 ]
ldr r4, =EMI_SDCONF1
ldr r5, =0x1E184177
str r5, [
r4 ]
ldr r4, =EMI_SDCONF2
ldr r5, =0x80001860
str r5, [
r4 ]
remap:
mov r0, pc
add r0, r0, #0x20000000
add r0, r0, #0x08
mov pc, r0
mov r0, r0
mov r0, r0
mov r0, r0
mov r0, r0
ldr r4, =0x11000020
ldr r5, =0xb //remap到sdram中
str r5, [
r4 ]
ldr r0, = 0
ldr r1, _bss_start
ldr r2, _bss_end
bss_init:
str r0, [r1]
add r1,r1,#4
cmp r1,r2
blt bss_init
#ifndef
CONFIG_SKIP_RELOCATE_UBOOT
relocate:
adr r0,
_start
ldr r1,
_TEXT_BASE
cmp r0,
r1
beq vector_copy //如果相等则说明已经在sdram中,这时候只需要搬运中断向量表
ldr r2,
_armboot_start
ldr r3,
_bss_start
sub r2,
r3, r2
add r2,
r0, r2
copy_loop: //正真的代码搬运过程
ldmia r0!,
{r3-r10}
stmia r1!,
{r3-r10}
cmp r0,
r2
ble copy_loop
vector_copy:
ldr r0,
_TEXT_BASE
add r2,
r0, #128
ldr r1,
=0x30000000
vector_copy_loop://搬运中断向量表的循环
ldmia r0!,
{r3-r10}
stmia r1!,
{r3-r10}
cmp r0,
r2
ble vector_copy_loop
#endif
mrs R4,
cpsr
bic R4,
R4, #0x80
msr cpsr,
R4
ldr pc,
_start_armboot
_start_armboot: .word
start_armboot
相关文章推荐
- Arm linux启动分析(2)
- Arm linux启动分析(2)
- Arm linux启动分析(3)
- Arm linux启动分析(3)
- Arm linux启动分析(4)
- Arm linux启动分析(4)
- Arm linux启动分析(5)
- Arm linux启动分析(1)
- Arm linux启动分析(1)
- ARM&LINUX学习笔记(6)------启动代码分析
- Arm linux 启动流程
- Arm linux 启动流程
- 制作CDLinux 启动U盘
- Linux 内核分析
- linux .mp3 后台播放(arm)
- ARM linux的启动部分源代码简略分析【转】
- linux启动优化:mdev -s自从…
- 分析Android 根文件系统启动…
- linux内核启动过程分析(一) arm
- 基于ARM 的Linux 的启动分析报告——ARM+Linux的启动分析(2)