Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OS
U-Boot.Mirror
提交
0ddc9c17
U
U-Boot.Mirror
项目概览
OS
/
U-Boot.Mirror
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
U-Boot.Mirror
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
0ddc9c17
编写于
7月 26, 2017
作者:
T
Tom Rini
浏览文件
操作
浏览文件
下载
差异文件
Merge
git://git.denx.de/u-boot-mips
上级
dc5210a2
e94136bd
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
678 addition
and
185 deletion
+678
-185
Makefile
Makefile
+5
-2
arch/mips/Makefile.postlink
arch/mips/Makefile.postlink
+23
-0
arch/mips/config.mk
arch/mips/config.mk
+5
-16
arch/mips/cpu/start.S
arch/mips/cpu/start.S
+0
-130
arch/mips/cpu/u-boot.lds
arch/mips/cpu/u-boot.lds
+9
-32
arch/mips/include/asm/relocs.h
arch/mips/include/asm/relocs.h
+24
-0
arch/mips/include/asm/sections.h
arch/mips/include/asm/sections.h
+7
-0
arch/mips/lib/Makefile
arch/mips/lib/Makefile
+1
-0
arch/mips/lib/bootm.c
arch/mips/lib/bootm.c
+4
-4
arch/mips/lib/reloc.c
arch/mips/lib/reloc.c
+164
-0
common/board_f.c
common/board_f.c
+1
-1
tools/.gitignore
tools/.gitignore
+1
-0
tools/Makefile
tools/Makefile
+2
-0
tools/mips-relocs.c
tools/mips-relocs.c
+432
-0
未找到文件。
Makefile
浏览文件 @
0ddc9c17
...
@@ -1232,13 +1232,16 @@ u-boot.elf: u-boot.bin
...
@@ -1232,13 +1232,16 @@ u-boot.elf: u-boot.bin
$(Q)$(OBJCOPY)
-I
binary
$(PLATFORM_ELFFLAGS)
$<
u-boot-elf.o
$(Q)$(OBJCOPY)
-I
binary
$(PLATFORM_ELFFLAGS)
$<
u-boot-elf.o
$(
call
if_changed,u-boot-elf
)
$(
call
if_changed,u-boot-elf
)
ARCH_POSTLINK
:=
$(
wildcard
$(srctree)
/arch/
$(ARCH)
/Makefile.postlink
)
# Rule to link u-boot
# Rule to link u-boot
# May be overridden by arch/$(ARCH)/config.mk
# May be overridden by arch/$(ARCH)/config.mk
quiet_cmd_u-boot__
?=
LD
$@
quiet_cmd_u-boot__
?=
LD
$@
cmd_u-boot__
?=
$(LD)
$(LDFLAGS)
$
(
LDFLAGS_u-boot
)
-o
$@
\
cmd_u-boot__
?=
$(LD)
$(LDFLAGS)
$
(
LDFLAGS_u-boot
)
-o
$@
\
-T
u-boot.lds
$
(
u-boot-init
)
\
-T
u-boot.lds
$
(
u-boot-init
)
\
--start-group
$
(
u-boot-main
)
--end-group
\
--start-group
$
(
u-boot-main
)
--end-group
\
$(PLATFORM_LIBS)
-Map
u-boot.map
$(PLATFORM_LIBS)
-Map
u-boot.map
;
\
$(
if
$(ARCH_POSTLINK)
,
$(MAKE)
-f
$(ARCH_POSTLINK)
$@
,
true
)
quiet_cmd_smap
=
GEN common/system_map.o
quiet_cmd_smap
=
GEN common/system_map.o
cmd_smap
=
\
cmd_smap
=
\
...
@@ -1248,7 +1251,7 @@ cmd_smap = \
...
@@ -1248,7 +1251,7 @@ cmd_smap = \
-c
$(srctree)
/common/system_map.c
-o
common/system_map.o
-c
$(srctree)
/common/system_map.c
-o
common/system_map.o
u-boot
:
$(u-boot-init) $(u-boot-main) u-boot.lds FORCE
u-boot
:
$(u-boot-init) $(u-boot-main) u-boot.lds FORCE
$(
call
if_changed,u-boot__
)
+
$(
call
if_changed,u-boot__
)
ifeq
($(CONFIG_KALLSYMS),y)
ifeq
($(CONFIG_KALLSYMS),y)
$(
call
cmd,smap
)
$(
call
cmd,smap
)
$(
call
cmd,u-boot__
)
common/system_map.o
$(
call
cmd,u-boot__
)
common/system_map.o
...
...
arch/mips/Makefile.postlink
0 → 100644
浏览文件 @
0ddc9c17
#
# Copyright (c) 2017 Imagination Technologies Ltd.
#
# SPDX-License-Identifier: GPL-2.0+
#
PHONY
:=
__archpost
__archpost
:
-include
include/config/auto.conf
include
scripts/Kbuild.include
CMD_RELOCS
=
tools/mips-relocs
quiet_cmd_relocs
=
RELOCS
$@
cmd_relocs
=
$(CMD_RELOCS)
$@
u-boot
:
FORCE
@
true
$(
call
if_changed,relocs
)
.PHONY
:
FORCE
FORCE
:
arch/mips/config.mk
浏览文件 @
0ddc9c17
...
@@ -56,25 +56,14 @@ PLATFORM_ELFFLAGS += -B mips $(OBJCOPYFLAGS)
...
@@ -56,25 +56,14 @@ PLATFORM_ELFFLAGS += -B mips $(OBJCOPYFLAGS)
# LDFLAGS_vmlinux += -G 0 -static -n -nostdlib
# LDFLAGS_vmlinux += -G 0 -static -n -nostdlib
# MODFLAGS += -mlong-calls
# MODFLAGS += -mlong-calls
#
#
# On the other hand, we want PIC in the U-Boot code to relocate it from ROM
ifndef
CONFIG_SPL_BUILD
# to RAM. $28 is always used as gp.
OBJCOPYFLAGS
+=
-j
.got
-j
.rel
-j
.padding
-j
.dtb.init.rodata
#
LDFLAGS_FINAL
+=
--emit-relocs
ifdef
CONFIG_SPL_BUILD
PF_ABICALLS
:=
-mno-abicalls
PF_PIC
:=
-fno-pic
PF_PIE
:=
else
PF_ABICALLS
:=
-mabicalls
PF_PIC
:=
-fpic
PF_PIE
:=
-pie
PF_OBJCOPY
:=
-j
.got
-j
.rel.dyn
-j
.padding
PF_OBJCOPY
+=
-j
.dtb.init.rodata
endif
endif
PLATFORM_CPPFLAGS
+=
-G
0
$(PF_ABICALLS)
$(PF_PIC)
PLATFORM_CPPFLAGS
+=
-G
0
-mno-abicalls
-fno-pic
PLATFORM_CPPFLAGS
+=
-msoft-float
PLATFORM_CPPFLAGS
+=
-msoft-float
PLATFORM_LDFLAGS
+=
-G
0
-static
-n
-nostdlib
PLATFORM_LDFLAGS
+=
-G
0
-static
-n
-nostdlib
PLATFORM_RELFLAGS
+=
-ffunction-sections
-fdata-sections
PLATFORM_RELFLAGS
+=
-ffunction-sections
-fdata-sections
LDFLAGS_FINAL
+=
--gc-sections
$(PF_PIE)
LDFLAGS_FINAL
+=
--gc-sections
OBJCOPYFLAGS
+=
-j
.text
-j
.rodata
-j
.data
-j
.u_boot_list
OBJCOPYFLAGS
+=
-j
.text
-j
.rodata
-j
.data
-j
.u_boot_list
OBJCOPYFLAGS
+=
$(PF_OBJCOPY)
arch/mips/cpu/start.S
浏览文件 @
0ddc9c17
...
@@ -221,18 +221,6 @@ wr_done:
...
@@ -221,18 +221,6 @@ wr_done:
ehb
ehb
#endif
#endif
/
*
*
Initialize
$gp
,
force
pointer
sized
alignment
of
bal
instruction
to
*
forbid
the
compiler
to
put
nop
's between bal and _gp. This is
*
required
to
keep
_gp
and
ra
aligned
to
8
byte
.
*/
.
align
PTRLOG
bal
1
f
nop
PTR
_gp
1
:
PTR_L
gp
,
0
(
ra
)
#ifdef CONFIG_MIPS_CM
#ifdef CONFIG_MIPS_CM
PTR_LA
t9
,
mips_cm_map
PTR_LA
t9
,
mips_cm_map
jalr
t9
jalr
t9
...
@@ -291,121 +279,3 @@ wr_done:
...
@@ -291,121 +279,3 @@ wr_done:
move
ra
,
zero
move
ra
,
zero
END
(
_start
)
END
(
_start
)
/*
*
void
relocate_code
(
addr_sp
,
gd
,
addr_moni
)
*
*
This
"function"
does
not
return
,
instead
it
continues
in
RAM
*
after
relocating
the
monitor
code
.
*
*
a0
=
addr_sp
*
a1
=
gd
*
a2
=
destination
address
*/
ENTRY
(
relocate_code
)
move
sp
,
a0
#
set
new
stack
pointer
move
fp
,
sp
move
s0
,
a1
#
save
gd
in
s0
move
s2
,
a2
#
save
destination
address
in
s2
PTR_LI
t0
,
CONFIG_SYS_MONITOR_BASE
PTR_SUB
s1
,
s2
,
t0
#
s1
<--
relocation
offset
PTR_LA
t2
,
__image_copy_end
move
t1
,
a2
/
*
*
t0
=
source
address
*
t1
=
target
address
*
t2
=
source
end
address
*/
1
:
PTR_L
t3
,
0
(
t0
)
PTR_S
t3
,
0
(
t1
)
PTR_ADDU
t0
,
PTRSIZE
blt
t0
,
t2
,
1
b
PTR_ADDU
t1
,
PTRSIZE
/
*
*
Now
we
want
to
update
GOT
.
*
*
GOT
[
0
]
is
reserved
.
GOT
[
1
]
is
also
reserved
for
the
dynamic
object
*
generated
by
GNU
ld
.
Skip
these
reserved
entries
from
relocation
.
*/
PTR_LA
t3
,
num_got_entries
PTR_LA
t8
,
_GLOBAL_OFFSET_TABLE_
PTR_ADD
t8
,
s1
#
t8
now
holds
relocated
_G_O_T_
PTR_ADDIU
t8
,
t8
,
2
*
PTRSIZE
#
skipping
first
two
entries
PTR_LI
t2
,
2
1
:
PTR_L
t1
,
0
(
t8
)
beqz
t1
,
2
f
PTR_ADD
t1
,
s1
PTR_S
t1
,
0
(
t8
)
2
:
PTR_ADDIU
t2
,
1
blt
t2
,
t3
,
1
b
PTR_ADDIU
t8
,
PTRSIZE
/
*
Update
dynamic
relocations
*/
PTR_LA
t1
,
__rel_dyn_start
PTR_LA
t2
,
__rel_dyn_end
b
2
f
#
skip
first
reserved
entry
PTR_ADDIU
t1
,
2
*
PTRSIZE
1
:
lw
t8
,
-
4
(
t1
)
#
t8
<--
relocation
info
PTR_LI
t3
,
MIPS_RELOC
bne
t8
,
t3
,
2
f
#
skip
non
-
MIPS_RELOC
entries
nop
PTR_L
t3
,
-(
2
*
PTRSIZE
)(
t1
)
#
t3
<--
location
to
fix
up
in
FLASH
PTR_L
t8
,
0
(
t3
)
#
t8
<--
original
pointer
PTR_ADD
t8
,
s1
#
t8
<--
adjusted
pointer
PTR_ADD
t3
,
s1
#
t3
<--
location
to
fix
up
in
RAM
PTR_S
t8
,
0
(
t3
)
2
:
blt
t1
,
t2
,
1
b
PTR_ADDIU
t1
,
2
*
PTRSIZE
#
each
rel
.
dyn
entry
is
2
*
PTRSIZE
bytes
/
*
*
Flush
caches
to
ensure
our
newly
modified
instructions
are
visible
*
to
the
instruction
cache
.
We
're still running with the old GOT, so
*
apply
the
reloc
offset
to
the
start
address
.
*/
PTR_LA
a0
,
__text_start
PTR_LA
a1
,
__text_end
PTR_SUB
a1
,
a1
,
a0
PTR_LA
t9
,
flush_cache
jalr
t9
PTR_ADD
a0
,
s1
PTR_ADD
gp
,
s1
#
adjust
gp
/
*
*
Clear
BSS
*
*
GOT
is
now
relocated
.
Thus
__bss_start
and
__bss_end
can
be
*
accessed
directly
via
$gp.
*/
PTR_LA
t1
,
__bss_start
#
t1
<--
__bss_start
PTR_LA
t2
,
__bss_end
#
t2
<--
__bss_end
1
:
PTR_S
zero
,
0
(
t1
)
blt
t1
,
t2
,
1
b
PTR_ADDIU
t1
,
PTRSIZE
move
a0
,
s0
#
a0
<--
gd
move
a1
,
s2
PTR_LA
t9
,
board_init_r
jr
t9
move
ra
,
zero
END
(
relocate_code
)
arch/mips/cpu/u-boot.lds
浏览文件 @
0ddc9c17
...
@@ -34,15 +34,6 @@ SECTIONS
...
@@ -34,15 +34,6 @@ SECTIONS
*(.data*)
*(.data*)
}
}
. = .;
_gp = ALIGN(16) + 0x7ff0;
.got : {
*(.got)
}
num_got_entries = SIZEOF(.got) >> PTR_COUNT_SHIFT;
. = ALIGN(4);
. = ALIGN(4);
.sdata : {
.sdata : {
*(.sdata*)
*(.sdata*)
...
@@ -57,33 +48,19 @@ SECTIONS
...
@@ -57,33 +48,19 @@ SECTIONS
__image_copy_end = .;
__image_copy_end = .;
__init_end = .;
__init_end = .;
.rel.dyn : {
/*
__rel_dyn_start = .;
* .rel must come last so that the mips-relocs tool can shrink
*(.rel.dyn)
* the section size & the PT_LOAD program header filesz.
__rel_dyn_end = .;
*/
}
.rel : {
__rel_start = .;
.padding : {
BYTE(0x0)
/*
. += (32 * 1024) - 1;
* Workaround for a binutils feature (or bug?).
*
* The GNU ld from binutils puts the dynamic relocation
* entries into the .rel.dyn section. Sometimes it
* allocates more dynamic relocation entries than it needs
* and the unused slots are set to R_MIPS_NONE entries.
*
* However the size of the .rel.dyn section in the ELF
* section header does not cover the unused entries, so
* objcopy removes those during stripping.
*
* Create a small section here to avoid that.
*/
LONG(0xFFFFFFFF)
}
}
_end = .;
_end = .;
.bss __rel_
dyn_
start (OVERLAY) : {
.bss __rel_start (OVERLAY) : {
__bss_start = .;
__bss_start = .;
*(.sbss.*)
*(.sbss.*)
*(.bss.*)
*(.bss.*)
...
...
arch/mips/include/asm/relocs.h
0 → 100644
浏览文件 @
0ddc9c17
/*
* MIPS Relocations
*
* Copyright (c) 2017 Imagination Technologies Ltd.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __ASM_MIPS_RELOCS_H__
#define __ASM_MIPS_RELOCS_H__
#define R_MIPS_NONE 0
#define R_MIPS_32 2
#define R_MIPS_26 4
#define R_MIPS_HI16 5
#define R_MIPS_LO16 6
#define R_MIPS_PC16 10
#define R_MIPS_64 18
#define R_MIPS_HIGHER 28
#define R_MIPS_HIGHEST 29
#define R_MIPS_PC21_S2 60
#define R_MIPS_PC26_S2 61
#endif
/* __ASM_MIPS_RELOCS_H__ */
arch/mips/include/asm/sections.h
浏览文件 @
0ddc9c17
...
@@ -8,4 +8,11 @@
...
@@ -8,4 +8,11 @@
#include <asm-generic/sections.h>
#include <asm-generic/sections.h>
/**
* __rel_start: Relocation data generated by the mips-relocs tool
*
* See arch/mips/lib/reloc.c for details on the format & use of this data.
*/
extern
uint8_t
__rel_start
[];
#endif
#endif
arch/mips/lib/Makefile
浏览文件 @
0ddc9c17
...
@@ -8,6 +8,7 @@
...
@@ -8,6 +8,7 @@
obj-y
+=
cache.o
obj-y
+=
cache.o
obj-y
+=
cache_init.o
obj-y
+=
cache_init.o
obj-y
+=
genex.o
obj-y
+=
genex.o
obj-y
+=
reloc.o
obj-y
+=
stack.o
obj-y
+=
stack.o
obj-y
+=
traps.o
obj-y
+=
traps.o
...
...
arch/mips/lib/bootm.c
浏览文件 @
0ddc9c17
...
@@ -279,17 +279,17 @@ static void boot_prep_linux(bootm_headers_t *images)
...
@@ -279,17 +279,17 @@ static void boot_prep_linux(bootm_headers_t *images)
boot_reloc_fdt
(
images
);
boot_reloc_fdt
(
images
);
boot_setup_fdt
(
images
);
boot_setup_fdt
(
images
);
}
else
{
}
else
{
if
(
CONFIG_IS_ENABLED
(
CONFIG_MIPS_BOOT_ENV_LEGACY
))
linux_env_legacy
(
images
);
if
(
CONFIG_IS_ENABLED
(
MIPS_BOOT_CMDLINE_LEGACY
))
{
if
(
CONFIG_IS_ENABLED
(
MIPS_BOOT_CMDLINE_LEGACY
))
{
linux_cmdline_legacy
(
images
);
linux_cmdline_legacy
(
images
);
if
(
!
CONFIG_IS_ENABLED
(
CONFIG_
MIPS_BOOT_ENV_LEGACY
))
if
(
!
CONFIG_IS_ENABLED
(
MIPS_BOOT_ENV_LEGACY
))
linux_cmdline_append
(
images
);
linux_cmdline_append
(
images
);
linux_cmdline_dump
();
linux_cmdline_dump
();
}
}
if
(
CONFIG_IS_ENABLED
(
MIPS_BOOT_ENV_LEGACY
))
linux_env_legacy
(
images
);
}
}
}
}
...
...
arch/mips/lib/reloc.c
0 → 100644
浏览文件 @
0ddc9c17
/*
* MIPS Relocation
*
* Copyright (c) 2017 Imagination Technologies Ltd.
*
* SPDX-License-Identifier: GPL-2.0+
*
* Relocation data, found in the .rel section, is generated by the mips-relocs
* tool & contains a record of all locations in the U-Boot binary that need to
* be fixed up during relocation.
*
* The data is a sequence of unsigned integers, which are of somewhat arbitrary
* size. This is achieved by encoding integers as a sequence of bytes, each of
* which contains 7 bits of data with the most significant bit indicating
* whether any further bytes need to be read. The least significant bits of the
* integer are found in the first byte - ie. it somewhat resembles little
* endian.
*
* Each pair of two integers represents a relocation that must be applied. The
* first integer represents the type of relocation as a standard ELF relocation
* type (ie. R_MIPS_*). The second integer represents the offset at which to
* apply the relocation, relative to the previous relocation or for the first
* relocation the start of the relocated .text section.
*
* The end of the relocation data is indicated when type R_MIPS_NONE (0) is
* read, at which point no further integers should be read. That is, the
* terminating R_MIPS_NONE reloc includes no offset.
*/
#include <common.h>
#include <asm/relocs.h>
#include <asm/sections.h>
/**
* read_uint() - Read an unsigned integer from the buffer
* @buf: pointer to a pointer to the reloc buffer
*
* Read one whole unsigned integer from the relocation data pointed to by @buf,
* advancing @buf past the bytes encoding the integer.
*
* Returns: the integer read from @buf
*/
static
unsigned
long
read_uint
(
uint8_t
**
buf
)
{
unsigned
long
val
=
0
;
unsigned
int
shift
=
0
;
uint8_t
new
;
do
{
new
=
*
(
*
buf
)
++
;
val
|=
(
new
&
0x7f
)
<<
shift
;
shift
+=
7
;
}
while
(
new
&
0x80
);
return
val
;
}
/**
* apply_reloc() - Apply a single relocation
* @type: the type of reloc (R_MIPS_*)
* @addr: the address that the reloc should be applied to
* @off: the relocation offset, ie. number of bytes we're moving U-Boot by
*
* Apply a single relocation of type @type at @addr. This function is
* intentionally simple, and does the bare minimum needed to fixup the
* relocated U-Boot - in particular, it does not check for overflows.
*/
static
void
apply_reloc
(
unsigned
int
type
,
void
*
addr
,
long
off
)
{
uint32_t
u32
;
switch
(
type
)
{
case
R_MIPS_26
:
u32
=
*
(
uint32_t
*
)
addr
;
u32
=
(
u32
&
GENMASK
(
31
,
26
))
|
((
u32
+
(
off
>>
2
))
&
GENMASK
(
25
,
0
));
*
(
uint32_t
*
)
addr
=
u32
;
break
;
case
R_MIPS_32
:
*
(
uint32_t
*
)
addr
+=
off
;
break
;
case
R_MIPS_64
:
*
(
uint64_t
*
)
addr
+=
off
;
break
;
case
R_MIPS_HI16
:
*
(
uint32_t
*
)
addr
+=
off
>>
16
;
break
;
default:
panic
(
"Unhandled reloc type %u
\n
"
,
type
);
}
}
/**
* relocate_code() - Relocate U-Boot, generally from flash to DDR
* @start_addr_sp: new stack pointer
* @new_gd: pointer to relocated global data
* @relocaddr: the address to relocate to
*
* Relocate U-Boot from its current location (generally in flash) to a new one
* (generally in DDR). This function will copy the U-Boot binary & apply
* relocations as necessary, then jump to board_init_r in the new build of
* U-Boot. As such, this function does not return.
*/
void
relocate_code
(
ulong
start_addr_sp
,
gd_t
*
new_gd
,
ulong
relocaddr
)
{
unsigned
long
addr
,
length
,
bss_len
;
uint8_t
*
buf
,
*
bss_start
;
unsigned
int
type
;
long
off
;
/*
* Ensure that we're relocating by an offset which is a multiple of
* 64KiB, ie. doesn't change the least significant 16 bits of any
* addresses. This allows us to discard R_MIPS_LO16 relocs, saving
* space in the U-Boot binary & complexity in handling them.
*/
off
=
relocaddr
-
(
unsigned
long
)
__text_start
;
if
(
off
&
0xffff
)
panic
(
"Mis-aligned relocation
\n
"
);
/* Copy U-Boot to RAM */
length
=
__image_copy_end
-
__text_start
;
memcpy
((
void
*
)
relocaddr
,
__text_start
,
length
);
/* Now apply relocations to the copy in RAM */
buf
=
__rel_start
;
addr
=
relocaddr
;
while
(
true
)
{
type
=
read_uint
(
&
buf
);
if
(
type
==
R_MIPS_NONE
)
break
;
addr
+=
read_uint
(
&
buf
)
<<
2
;
apply_reloc
(
type
,
(
void
*
)
addr
,
off
);
}
/* Ensure the icache is coherent */
flush_cache
(
relocaddr
,
length
);
/* Clear the .bss section */
bss_start
=
(
uint8_t
*
)((
unsigned
long
)
__bss_start
+
off
);
bss_len
=
(
unsigned
long
)
&
__bss_end
-
(
unsigned
long
)
__bss_start
;
memset
(
bss_start
,
0
,
bss_len
);
/* Jump to the relocated U-Boot */
asm
volatile
(
"move $29, %0
\n
"
" move $4, %1
\n
"
" move $5, %2
\n
"
" move $31, $0
\n
"
" jr %3"
:
/* no outputs */
:
"r"
(
start_addr_sp
),
"r"
(
new_gd
),
"r"
(
relocaddr
),
"r"
((
unsigned
long
)
board_init_r
+
off
));
/* Since we jumped to the new U-Boot above, we won't get here */
unreachable
();
}
common/board_f.c
浏览文件 @
0ddc9c17
...
@@ -418,7 +418,7 @@ static int reserve_uboot(void)
...
@@ -418,7 +418,7 @@ static int reserve_uboot(void)
*/
*/
gd
->
relocaddr
-=
gd
->
mon_len
;
gd
->
relocaddr
-=
gd
->
mon_len
;
gd
->
relocaddr
&=
~
(
4096
-
1
);
gd
->
relocaddr
&=
~
(
4096
-
1
);
#if
def CONFIG_E500
#if
defined(CONFIG_E500) || defined(CONFIG_MIPS)
/* round down to next 64 kB limit so that IVPR stays aligned */
/* round down to next 64 kB limit so that IVPR stays aligned */
gd
->
relocaddr
&=
~
(
65536
-
1
);
gd
->
relocaddr
&=
~
(
65536
-
1
);
#endif
#endif
...
...
tools/.gitignore
浏览文件 @
0ddc9c17
...
@@ -11,6 +11,7 @@
...
@@ -11,6 +11,7 @@
/img2srec
/img2srec
/kwboot
/kwboot
/dumpimage
/dumpimage
/mips-relocs
/mkenvimage
/mkenvimage
/mkimage
/mkimage
/mkexynosspl
/mkexynosspl
...
...
tools/Makefile
浏览文件 @
0ddc9c17
...
@@ -211,6 +211,8 @@ hostprogs-$(CONFIG_STATIC_RELA) += relocate-rela
...
@@ -211,6 +211,8 @@ hostprogs-$(CONFIG_STATIC_RELA) += relocate-rela
hostprogs-y
+=
fdtgrep
hostprogs-y
+=
fdtgrep
fdtgrep-objs
+=
$(LIBFDT_OBJS)
fdtgrep.o
fdtgrep-objs
+=
$(LIBFDT_OBJS)
fdtgrep.o
hostprogs-$(CONFIG_MIPS)
+=
mips-relocs
# We build some files with extra pedantic flags to try to minimize things
# We build some files with extra pedantic flags to try to minimize things
# that won't build on some weird host compiler -- though there are lots of
# that won't build on some weird host compiler -- though there are lots of
# exceptions for files that aren't complaint.
# exceptions for files that aren't complaint.
...
...
tools/mips-relocs.c
0 → 100644
浏览文件 @
0ddc9c17
/*
* MIPS Relocation Data Generator
*
* Copyright (c) 2017 Imagination Technologies Ltd.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <assert.h>
#include <elf.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <asm/relocs.h>
#define hdr_field(pfx, idx, field) ({ \
uint64_t _val; \
unsigned int _size; \
\
if (is_64) { \
_val = pfx##hdr64[idx].field; \
_size = sizeof(pfx##hdr64[0].field); \
} else { \
_val = pfx##hdr32[idx].field; \
_size = sizeof(pfx##hdr32[0].field); \
} \
\
switch (_size) { \
case 1: \
break; \
case 2: \
_val = is_be ? be16toh(_val) : le16toh(_val); \
break; \
case 4: \
_val = is_be ? be32toh(_val) : le32toh(_val); \
break; \
case 8: \
_val = is_be ? be64toh(_val) : le64toh(_val); \
break; \
} \
\
_val; \
})
#define set_hdr_field(pfx, idx, field, val) ({ \
uint64_t _val; \
unsigned int _size; \
\
if (is_64) \
_size = sizeof(pfx##hdr64[0].field); \
else \
_size = sizeof(pfx##hdr32[0].field); \
\
switch (_size) { \
case 1: \
_val = val; \
break; \
case 2: \
_val = is_be ? htobe16(val) : htole16(val); \
break; \
case 4: \
_val = is_be ? htobe32(val) : htole32(val); \
break; \
case 8: \
_val = is_be ? htobe64(val) : htole64(val); \
break; \
default: \
/* We should never reach here */
\
_val = 0; \
assert(0); \
break; \
} \
\
if (is_64) \
pfx##hdr64[idx].field = _val; \
else \
pfx##hdr32[idx].field = _val; \
})
#define ehdr_field(field) \
hdr_field(e, 0, field)
#define phdr_field(idx, field) \
hdr_field(p, idx, field)
#define shdr_field(idx, field) \
hdr_field(s, idx, field)
#define set_phdr_field(idx, field, val) \
set_hdr_field(p, idx, field, val)
#define set_shdr_field(idx, field, val) \
set_hdr_field(s, idx, field, val)
#define shstr(idx) (&shstrtab[idx])
bool
is_64
,
is_be
;
uint64_t
text_base
;
struct
mips_reloc
{
uint8_t
type
;
uint64_t
offset
;
}
*
relocs
;
size_t
relocs_sz
,
relocs_idx
;
static
int
add_reloc
(
unsigned
int
type
,
uint64_t
off
)
{
struct
mips_reloc
*
new
;
size_t
new_sz
;
switch
(
type
)
{
case
R_MIPS_NONE
:
case
R_MIPS_LO16
:
case
R_MIPS_PC16
:
case
R_MIPS_HIGHER
:
case
R_MIPS_HIGHEST
:
case
R_MIPS_PC21_S2
:
case
R_MIPS_PC26_S2
:
/* Skip these relocs */
return
0
;
default:
break
;
}
if
(
relocs_idx
==
relocs_sz
)
{
new_sz
=
relocs_sz
?
relocs_sz
*
2
:
128
;
new
=
realloc
(
relocs
,
new_sz
*
sizeof
(
*
relocs
));
if
(
!
new
)
{
fprintf
(
stderr
,
"Out of memory
\n
"
);
return
-
ENOMEM
;
}
relocs
=
new
;
relocs_sz
=
new_sz
;
}
relocs
[
relocs_idx
++
]
=
(
struct
mips_reloc
){
.
type
=
type
,
.
offset
=
off
,
};
return
0
;
}
static
int
parse_mips32_rel
(
const
void
*
_rel
)
{
const
Elf32_Rel
*
rel
=
_rel
;
uint32_t
off
,
type
;
off
=
is_be
?
be32toh
(
rel
->
r_offset
)
:
le32toh
(
rel
->
r_offset
);
off
-=
text_base
;
type
=
is_be
?
be32toh
(
rel
->
r_info
)
:
le32toh
(
rel
->
r_info
);
type
=
ELF32_R_TYPE
(
type
);
return
add_reloc
(
type
,
off
);
}
static
int
parse_mips64_rela
(
const
void
*
_rel
)
{
const
Elf64_Rela
*
rel
=
_rel
;
uint64_t
off
,
type
;
off
=
is_be
?
be64toh
(
rel
->
r_offset
)
:
le64toh
(
rel
->
r_offset
);
off
-=
text_base
;
type
=
rel
->
r_info
>>
(
64
-
8
);
return
add_reloc
(
type
,
off
);
}
static
void
output_uint
(
uint8_t
**
buf
,
uint64_t
val
)
{
uint64_t
tmp
;
do
{
tmp
=
val
&
0x7f
;
val
>>=
7
;
tmp
|=
!!
val
<<
7
;
*
(
*
buf
)
++
=
tmp
;
}
while
(
val
);
}
static
int
compare_relocs
(
const
void
*
a
,
const
void
*
b
)
{
const
struct
mips_reloc
*
ra
=
a
,
*
rb
=
b
;
return
ra
->
offset
-
rb
->
offset
;
}
int
main
(
int
argc
,
char
*
argv
[])
{
unsigned
int
i
,
j
,
i_rel_shdr
,
sh_type
,
sh_entsize
,
sh_entries
;
size_t
rel_size
,
rel_actual_size
,
load_sz
;
const
char
*
shstrtab
,
*
sh_name
,
*
rel_pfx
;
int
(
*
parse_fn
)(
const
void
*
rel
);
uint8_t
*
buf_start
,
*
buf
;
const
Elf32_Ehdr
*
ehdr32
;
const
Elf64_Ehdr
*
ehdr64
;
uintptr_t
sh_offset
;
Elf32_Phdr
*
phdr32
;
Elf64_Phdr
*
phdr64
;
Elf32_Shdr
*
shdr32
;
Elf64_Shdr
*
shdr64
;
struct
stat
st
;
int
err
,
fd
;
void
*
elf
;
bool
skip
;
fd
=
open
(
argv
[
1
],
O_RDWR
);
if
(
fd
==
-
1
)
{
fprintf
(
stderr
,
"Unable to open input file %s
\n
"
,
argv
[
1
]);
err
=
errno
;
goto
out_ret
;
}
err
=
fstat
(
fd
,
&
st
);
if
(
err
)
{
fprintf
(
stderr
,
"Unable to fstat() input file
\n
"
);
goto
out_close_fd
;
}
elf
=
mmap
(
NULL
,
st
.
st_size
,
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
fd
,
0
);
if
(
elf
==
MAP_FAILED
)
{
fprintf
(
stderr
,
"Unable to mmap() input file
\n
"
);
err
=
errno
;
goto
out_close_fd
;
}
ehdr32
=
elf
;
ehdr64
=
elf
;
if
(
memcmp
(
&
ehdr32
->
e_ident
[
EI_MAG0
],
ELFMAG
,
SELFMAG
))
{
fprintf
(
stderr
,
"Input file is not an ELF
\n
"
);
err
=
-
EINVAL
;
goto
out_free_relocs
;
}
if
(
ehdr32
->
e_ident
[
EI_VERSION
]
!=
EV_CURRENT
)
{
fprintf
(
stderr
,
"Unrecognised ELF version
\n
"
);
err
=
-
EINVAL
;
goto
out_free_relocs
;
}
switch
(
ehdr32
->
e_ident
[
EI_CLASS
])
{
case
ELFCLASS32
:
is_64
=
false
;
break
;
case
ELFCLASS64
:
is_64
=
true
;
break
;
default:
fprintf
(
stderr
,
"Unrecognised ELF class
\n
"
);
err
=
-
EINVAL
;
goto
out_free_relocs
;
}
switch
(
ehdr32
->
e_ident
[
EI_DATA
])
{
case
ELFDATA2LSB
:
is_be
=
false
;
break
;
case
ELFDATA2MSB
:
is_be
=
true
;
break
;
default:
fprintf
(
stderr
,
"Unrecognised ELF data encoding
\n
"
);
err
=
-
EINVAL
;
goto
out_free_relocs
;
}
if
(
ehdr_field
(
e_type
)
!=
ET_EXEC
)
{
fprintf
(
stderr
,
"Input ELF is not an executable
\n
"
);
printf
(
"type 0x%lx
\n
"
,
ehdr_field
(
e_type
));
err
=
-
EINVAL
;
goto
out_free_relocs
;
}
if
(
ehdr_field
(
e_machine
)
!=
EM_MIPS
)
{
fprintf
(
stderr
,
"Input ELF does not target MIPS
\n
"
);
err
=
-
EINVAL
;
goto
out_free_relocs
;
}
phdr32
=
elf
+
ehdr_field
(
e_phoff
);
phdr64
=
elf
+
ehdr_field
(
e_phoff
);
shdr32
=
elf
+
ehdr_field
(
e_shoff
);
shdr64
=
elf
+
ehdr_field
(
e_shoff
);
shstrtab
=
elf
+
shdr_field
(
ehdr_field
(
e_shstrndx
),
sh_offset
);
i_rel_shdr
=
UINT_MAX
;
for
(
i
=
0
;
i
<
ehdr_field
(
e_shnum
);
i
++
)
{
sh_name
=
shstr
(
shdr_field
(
i
,
sh_name
));
if
(
!
strcmp
(
sh_name
,
".rel"
))
{
i_rel_shdr
=
i
;
continue
;
}
if
(
!
strcmp
(
sh_name
,
".text"
))
{
text_base
=
shdr_field
(
i
,
sh_addr
);
continue
;
}
}
if
(
i_rel_shdr
==
UINT_MAX
)
{
fprintf
(
stderr
,
"Unable to find .rel section
\n
"
);
err
=
-
EINVAL
;
goto
out_free_relocs
;
}
if
(
!
text_base
)
{
fprintf
(
stderr
,
"Unable to find .text base address
\n
"
);
err
=
-
EINVAL
;
goto
out_free_relocs
;
}
rel_pfx
=
is_64
?
".rela."
:
".rel."
;
for
(
i
=
0
;
i
<
ehdr_field
(
e_shnum
);
i
++
)
{
sh_type
=
shdr_field
(
i
,
sh_type
);
if
((
sh_type
!=
SHT_REL
)
&&
(
sh_type
!=
SHT_RELA
))
continue
;
sh_name
=
shstr
(
shdr_field
(
i
,
sh_name
));
if
(
strncmp
(
sh_name
,
rel_pfx
,
strlen
(
rel_pfx
)))
{
if
(
strcmp
(
sh_name
,
".rel"
)
&&
strcmp
(
sh_name
,
".rel.dyn"
))
fprintf
(
stderr
,
"WARNING: Unexpected reloc section name '%s'
\n
"
,
sh_name
);
continue
;
}
/*
* Skip reloc sections which either don't correspond to another
* section in the ELF, or whose corresponding section isn't
* loaded as part of the U-Boot binary (ie. doesn't have the
* alloc flags set).
*/
skip
=
true
;
for
(
j
=
0
;
j
<
ehdr_field
(
e_shnum
);
j
++
)
{
if
(
strcmp
(
&
sh_name
[
strlen
(
rel_pfx
)
-
1
],
shstr
(
shdr_field
(
j
,
sh_name
))))
continue
;
skip
=
!
(
shdr_field
(
j
,
sh_flags
)
&
SHF_ALLOC
);
break
;
}
if
(
skip
)
continue
;
sh_offset
=
shdr_field
(
i
,
sh_offset
);
sh_entsize
=
shdr_field
(
i
,
sh_entsize
);
sh_entries
=
shdr_field
(
i
,
sh_size
)
/
sh_entsize
;
if
(
sh_type
==
SHT_REL
)
{
if
(
is_64
)
{
fprintf
(
stderr
,
"REL-style reloc in MIPS64 ELF?
\n
"
);
err
=
-
EINVAL
;
goto
out_free_relocs
;
}
else
{
parse_fn
=
parse_mips32_rel
;
}
}
else
{
if
(
is_64
)
{
parse_fn
=
parse_mips64_rela
;
}
else
{
fprintf
(
stderr
,
"RELA-style reloc in MIPS32 ELF?
\n
"
);
err
=
-
EINVAL
;
goto
out_free_relocs
;
}
}
for
(
j
=
0
;
j
<
sh_entries
;
j
++
)
{
err
=
parse_fn
(
elf
+
sh_offset
+
(
j
*
sh_entsize
));
if
(
err
)
goto
out_free_relocs
;
}
}
/* Sort relocs in ascending order of offset */
qsort
(
relocs
,
relocs_idx
,
sizeof
(
*
relocs
),
compare_relocs
);
/* Make reloc offsets relative to their predecessor */
for
(
i
=
relocs_idx
-
1
;
i
>
0
;
i
--
)
relocs
[
i
].
offset
-=
relocs
[
i
-
1
].
offset
;
/* Write the relocations to the .rel section */
buf
=
buf_start
=
elf
+
shdr_field
(
i_rel_shdr
,
sh_offset
);
for
(
i
=
0
;
i
<
relocs_idx
;
i
++
)
{
output_uint
(
&
buf
,
relocs
[
i
].
type
);
output_uint
(
&
buf
,
relocs
[
i
].
offset
>>
2
);
}
/* Write a terminating R_MIPS_NONE (0) */
output_uint
(
&
buf
,
R_MIPS_NONE
);
/* Ensure the relocs didn't overflow the .rel section */
rel_size
=
shdr_field
(
i_rel_shdr
,
sh_size
);
rel_actual_size
=
buf
-
buf_start
;
if
(
rel_actual_size
>
rel_size
)
{
fprintf
(
stderr
,
"Relocs overflowed .rel section
\n
"
);
return
-
ENOMEM
;
}
/* Update the .rel section's size */
set_shdr_field
(
i_rel_shdr
,
sh_size
,
rel_actual_size
);
/* Shrink the PT_LOAD program header filesz (ie. shrink u-boot.bin) */
for
(
i
=
0
;
i
<
ehdr_field
(
e_phnum
);
i
++
)
{
if
(
phdr_field
(
i
,
p_type
)
!=
PT_LOAD
)
continue
;
load_sz
=
phdr_field
(
i
,
p_filesz
);
load_sz
-=
rel_size
-
rel_actual_size
;
set_phdr_field
(
i
,
p_filesz
,
load_sz
);
break
;
}
/* Make sure data is written back to the file */
err
=
msync
(
elf
,
st
.
st_size
,
MS_SYNC
);
if
(
err
)
{
fprintf
(
stderr
,
"Failed to msync: %d
\n
"
,
errno
);
goto
out_free_relocs
;
}
out_free_relocs:
free
(
relocs
);
munmap
(
elf
,
st
.
st_size
);
out_close_fd:
close
(
fd
);
out_ret:
return
err
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录