sunxi: non-FEL SPL boot support for sun7i

Add support for booting from an MMC card.

Signed-off-by: Stefan Roese <sr@denx.de>
Signed-off-by: Henrik Nordström <henrik@henriknordstrom.net>
Signed-off-by: Ian Campbell <ijc@hellion.org.uk>
Reviewed-by: Marek Vasut <marex@denx.de>
Cc: Tom Cubie <Mr.hipboi@gmail.com>
Reviewed-by: Tom Rini <trini@ti.com>
This commit is contained in:
Ian Campbell 2014-05-05 11:52:30 +01:00 committed by Albert ARIBAUD
parent e24ea55c04
commit 50827a5991
9 changed files with 255 additions and 0 deletions

View file

@ -937,6 +937,13 @@ OBJCOPYFLAGS_u-boot-spi.gph = -I binary -O binary --pad-to=$(CONFIG_SPL_PAD_TO)
u-boot-spi.gph: spl/u-boot-spl.gph u-boot.img FORCE
$(call if_changed,pad_cat)
ifneq ($(CONFIG_SUNXI),)
OBJCOPYFLAGS_u-boot-sunxi-with-spl.bin = -I binary -O binary \
--pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0xff
u-boot-sunxi-with-spl.bin: spl/sunxi-spl.bin u-boot.img FORCE
$(call if_changed,pad_cat)
endif
ifneq ($(CONFIG_TEGRA),)
OBJCOPYFLAGS_u-boot-nodtb-tegra.bin = -O binary --pad-to=$(CONFIG_SYS_TEXT_BASE)
u-boot-nodtb-tegra.bin: spl/u-boot-spl u-boot.bin FORCE
@ -1163,6 +1170,9 @@ spl/u-boot-spl.bin: spl/u-boot-spl
spl/u-boot-spl: tools prepare
$(Q)$(MAKE) obj=spl -f $(srctree)/spl/Makefile all
spl/sunxi-spl.bin: spl/u-boot-spl
@:
tpl/u-boot-tpl.bin: tools prepare
$(Q)$(MAKE) obj=tpl -f $(srctree)/spl/Makefile all CONFIG_TPL_BUILD=y

View file

@ -0,0 +1,8 @@
# Build a combined spl + u-boot image
ifdef CONFIG_SPL
ifndef CONFIG_SPL_BUILD
ifndef CONFIG_SPL_FEL
ALL-y += u-boot-sunxi-with-spl.bin
endif
endif
endif

View file

@ -0,0 +1,52 @@
/*
* (C) Copyright 2012
* Allwinner Technology Co., Ltd. <www.allwinnertech.com>
* Tom Cubie <tangliang@allwinnertech.com>
*
* Based on omap-common/u-boot-spl.lds:
*
* (C) Copyright 2002
* Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
*
* (C) Copyright 2010
* Texas Instruments, <www.ti.com>
* Aneesh V <aneesh@ti.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\
LENGTH = CONFIG_SPL_MAX_SIZE }
MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \
LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
.text :
{
__start = .;
arch/arm/cpu/armv7/start.o (.text)
*(.text*)
} > .sram
. = ALIGN(4);
.rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram
. = ALIGN(4);
.data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
. = ALIGN(4);
__image_copy_end = .;
_end = .;
.bss :
{
. = ALIGN(4);
__bss_start = .;
*(.bss*)
. = ALIGN(4);
__bss_end = .;
} > .sdram
}

View file

@ -379,6 +379,7 @@ Active arm armv7 rmobile renesas lager
Active arm armv7 s5pc1xx samsung goni s5p_goni - Przemyslaw Marczak <p.marczak@samsung.com>
Active arm armv7 s5pc1xx samsung smdkc100 smdkc100 - Minkyu Kang <mk7.kang@samsung.com>
Active arm armv7 socfpga altera socfpga socfpga_cyclone5 - -
Active arm armv7 sunxi - sunxi Cubietruck sun7i:CUBIETRUCK,SPL,SUNXI_GMAC,RGMII -
Active arm armv7 sunxi - sunxi Cubietruck_FEL sun7i:CUBIETRUCK,SPL_FEL,SUNXI_GMAC,RGMII -
Active arm armv7 u8500 st-ericsson snowball snowball - Mathieu Poirier <mathieu.poirier@linaro.org>
Active arm armv7 u8500 st-ericsson u8500 u8500_href - -

View file

@ -17,6 +17,11 @@
* High Level Configuration Options
*/
#define CONFIG_SUNXI /* sunxi family */
#ifdef CONFIG_SPL_BUILD
#ifndef CONFIG_SPL_FEL
#define CONFIG_SYS_THUMB_BUILD /* Thumbs mode to save space in SPL */
#endif
#endif
#include <asm/arch/cpu.h> /* get chip and board defs */
@ -121,11 +126,32 @@
#define CONFIG_SPL_SERIAL_SUPPORT
#define CONFIG_SPL_LIBGENERIC_SUPPORT
#ifdef CONFIG_SPL_FEL
#define CONFIG_SPL
#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/sunxi/u-boot-spl-fel.lds"
#define CONFIG_SPL_START_S_PATH "arch/arm/cpu/armv7/sunxi"
#define CONFIG_SPL_TEXT_BASE 0x2000
#define CONFIG_SPL_MAX_SIZE 0x4000 /* 16 KiB */
#else /* CONFIG_SPL */
#define CONFIG_SPL_BSS_START_ADDR 0x4ff80000
#define CONFIG_SPL_BSS_MAX_SIZE 0x80000 /* 512 KiB */
#define CONFIG_SPL_TEXT_BASE 0x20 /* sram start+header */
#define CONFIG_SPL_MAX_SIZE 0x5fe0 /* 24KB on sun4i/sun7i */
#define CONFIG_SPL_LIBDISK_SUPPORT
#define CONFIG_SPL_MMC_SUPPORT
#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/sunxi/u-boot-spl.lds"
#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 80 /* 40KiB */
#define CONFIG_SPL_PAD_TO 32768 /* decimal for 'dd' */
#endif /* CONFIG_SPL */
/* end of 32 KiB in sram */
#define LOW_LEVEL_SRAM_STACK 0x00008000 /* End of sram */
#define CONFIG_SPL_STACK LOW_LEVEL_SRAM_STACK

View file

@ -189,6 +189,12 @@ ifdef CONFIG_SAMSUNG
ALL-y += $(obj)/$(BOARD)-spl.bin
endif
ifdef CONFIG_SUNXI
ifndef CONFIG_SPL_FEL
ALL-y += $(obj)/sunxi-spl.bin
endif
endif
all: $(ALL-y)
ifdef CONFIG_SAMSUNG
@ -216,6 +222,13 @@ ifneq ($(CONFIG_SPL_TEXT_BASE),)
LDFLAGS_$(SPL_BIN) += -Ttext $(CONFIG_SPL_TEXT_BASE)
endif
ifdef CONFIG_SUNXI
quiet_cmd_mksunxiboot = MKSUNXI $@
cmd_mksunxiboot = $(objtree)/tools/mksunxiboot $< $@
$(obj)/sunxi-spl.bin: $(obj)/$(SPL_BIN).bin
$(call if_changed,mksunxiboot)
endif
quiet_cmd_u-boot-spl = LD $@
cmd_u-boot-spl = cd $(obj) && $(LD) $(LDFLAGS) $(LDFLAGS_$(@F)) \
$(patsubst $(obj)/%,%,$(u-boot-spl-init)) --start-group \

1
tools/.gitignore vendored
View file

@ -11,6 +11,7 @@
/mkexynosspl
/mpc86x_clk
/mxsboot
/mksunxiboot
/ncb
/proftool
/relocate-rela

View file

@ -131,6 +131,8 @@ hostprogs-$(CONFIG_MX23) += mxsboot$(SFX)
hostprogs-$(CONFIG_MX28) += mxsboot$(SFX)
HOSTCFLAGS_mxsboot$(SFX).o := -pedantic
hostprogs-$(CONFIG_SUNXI) += mksunxiboot$(SFX)
hostprogs-$(CONFIG_NETCONSOLE) += ncb$(SFX)
hostprogs-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1$(SFX)

142
tools/mksunxiboot.c Normal file
View file

@ -0,0 +1,142 @@
/*
* (C) Copyright 2007-2011
* Allwinner Technology Co., Ltd. <www.allwinnertech.com>
* Tom Cubie <tangliang@allwinnertech.com>
*
* a simple tool to generate bootable image for sunxi platform.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
/* boot head definition from sun4i boot code */
struct boot_file_head {
uint32_t b_instruction; /* one intruction jumping to real code */
uint8_t magic[8]; /* ="eGON.BT0" or "eGON.BT1", not C-style str */
uint32_t check_sum; /* generated by PC */
uint32_t length; /* generated by PC */
/*
* We use a simplified header, only filling in what is needed
* by the boot ROM. To be compatible with Allwinner tools we
* would need to implement the proper fields here instead of
* padding.
*/
uint8_t pad[12]; /* align to 32 bytes */
};
#define BOOT0_MAGIC "eGON.BT0"
#define STAMP_VALUE 0x5F0A6C39
/* check sum functon from sun4i boot code */
int gen_check_sum(struct boot_file_head *head_p)
{
uint32_t length;
uint32_t *buf;
uint32_t loop;
uint32_t i;
uint32_t sum;
length = head_p->length;
if ((length & 0x3) != 0) /* must 4-byte-aligned */
return -1;
buf = (uint32_t *)head_p;
head_p->check_sum = STAMP_VALUE; /* fill stamp */
loop = length >> 2;
/* calculate the sum */
for (i = 0, sum = 0; i < loop; i++)
sum += buf[i];
/* write back check sum */
head_p->check_sum = sum;
return 0;
}
#define ALIGN(x, a) __ALIGN_MASK((x), (typeof(x))(a)-1)
#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
#define SUN4I_SRAM_SIZE 0x7600 /* 0x7748+ is used by BROM */
#define SRAM_LOAD_MAX_SIZE (SUN4I_SRAM_SIZE - sizeof(struct boot_file_head))
#define BLOCK_SIZE 512
struct boot_img {
struct boot_file_head header;
char code[SRAM_LOAD_MAX_SIZE];
char pad[BLOCK_SIZE];
};
int main(int argc, char *argv[])
{
int fd_in, fd_out;
struct boot_img img;
unsigned file_size, load_size;
int count;
if (argc < 2) {
printf("\tThis program makes an input bin file to sun4i " \
"bootable image.\n" \
"\tUsage: %s input_file out_putfile\n", argv[0]);
return EXIT_FAILURE;
}
fd_in = open(argv[1], O_RDONLY);
if (fd_in < 0) {
perror("Open input file");
return EXIT_FAILURE;
}
memset(img.pad, 0, BLOCK_SIZE);
/* get input file size */
file_size = lseek(fd_in, 0, SEEK_END);
if (file_size > SRAM_LOAD_MAX_SIZE) {
fprintf(stderr, "ERROR: File too large!\n");
return EXIT_FAILURE;
} else {
load_size = ALIGN(file_size, sizeof(int));
}
fd_out = open(argv[2], O_WRONLY | O_CREAT, 0666);
if (fd_out < 0) {
perror("Open output file");
return EXIT_FAILURE;
}
/* read file to buffer to calculate checksum */
lseek(fd_in, 0, SEEK_SET);
count = read(fd_in, img.code, load_size);
if (count != load_size) {
perror("Reading input image");
return EXIT_FAILURE;
}
/* fill the header */
img.header.b_instruction = /* b instruction */
0xEA000000 | /* jump to the first instr after the header */
((sizeof(struct boot_file_head) / sizeof(int) - 2)
& 0x00FFFFFF);
memcpy(img.header.magic, BOOT0_MAGIC, 8); /* no '0' termination */
img.header.length =
ALIGN(load_size + sizeof(struct boot_file_head), BLOCK_SIZE);
gen_check_sum(&img.header);
count = write(fd_out, &img, img.header.length);
if (count != img.header.length) {
perror("Writing output");
return EXIT_FAILURE;
}
close(fd_in);
close(fd_out);
return EXIT_SUCCESS;
}