Add pre-bootloader (pbl) image support
This allows for creating a pre-bootloader binary for - nand boot - mmc boot - compressed image The pbl will be incharge of the lowlevel init if needed. The barebox will skip it. Import string functions from linux 3.4 (arch/arm/boot/compressed/string.c) and implement a dummy panic. For now on introduce dummy zbarebox* targets and c code that will contain later the decompressor. This only implemeted on ARM. This patch is based on Sascha Hauer <s.hauer@pengutronix.de> Add compressed image support patch Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
This commit is contained in:
parent
d4c42fb33d
commit
78867e2bbd
6
Makefile
6
Makefile
|
@ -474,6 +474,8 @@ CFLAGS += $(call cc-option,-Wno-pointer-sign,)
|
|||
# this default value
|
||||
export KBUILD_IMAGE ?= barebox
|
||||
|
||||
common-$(CONFIG_PBL_IMAGE) += pbl/
|
||||
|
||||
barebox-dirs := $(patsubst %/,%,$(filter %/, $(common-y)))
|
||||
|
||||
barebox-alldirs := $(sort $(barebox-dirs) $(patsubst %/,%,$(filter %/, \
|
||||
|
@ -520,7 +522,7 @@ barebox-lds := $(lds-y)
|
|||
# May be overridden by arch/$(ARCH)/Makefile
|
||||
quiet_cmd_barebox__ ?= LD $@
|
||||
cmd_barebox__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_barebox) -o $@ \
|
||||
-T $(barebox-lds) $(barebox-head) \
|
||||
-T $(barebox-lds) \
|
||||
--start-group $(barebox-common) --end-group \
|
||||
$(filter-out $(barebox-lds) $(barebox-common) FORCE ,$^)
|
||||
|
||||
|
@ -674,7 +676,9 @@ OBJCOPYFLAGS_barebox.bin = -O binary
|
|||
|
||||
barebox.bin: barebox FORCE
|
||||
$(call if_changed,objcopy)
|
||||
ifndef CONFIG_PBL_IMAGE
|
||||
$(call cmd,check_file_size,$(CONFIG_BAREBOX_MAX_IMAGE_SIZE))
|
||||
endif
|
||||
|
||||
ifdef CONFIG_X86
|
||||
barebox.S: barebox
|
||||
|
|
|
@ -4,6 +4,7 @@ config ARM
|
|||
select HAS_MODULES
|
||||
select HAVE_CONFIGURABLE_MEMORY_LAYOUT
|
||||
select HAVE_CONFIGURABLE_TEXT_BASE
|
||||
select HAVE_PBL_IMAGE
|
||||
default y
|
||||
|
||||
config ARM_AMBA
|
||||
|
|
|
@ -197,6 +197,13 @@ ifeq ($(CONFIG_ARCH_DAVINCI),y)
|
|||
KBUILD_IMAGE := barebox.ubl
|
||||
endif
|
||||
|
||||
pbl := arch/arm/pbl
|
||||
zbarebox.S zbarebox.bin zbarebox: barebox.bin
|
||||
$(Q)$(MAKE) $(build)=$(pbl) $(pbl)/$@
|
||||
|
||||
archclean:
|
||||
$(MAKE) $(clean)=$(pbl)
|
||||
|
||||
all: $(KBUILD_IMAGE)
|
||||
|
||||
archprepare: maketools
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
obj-y += cpu.o
|
||||
obj-$(CONFIG_ARM_EXCEPTIONS) += exceptions.o
|
||||
obj-$(CONFIG_ARM_EXCEPTIONS) += interrupts.o
|
||||
obj-y += start.o
|
||||
obj-y += start.o start-reset.o
|
||||
|
||||
#
|
||||
# Any variants can be called as start-armxyz.S
|
||||
|
@ -15,3 +15,4 @@ obj-$(CONFIG_CPU_32v6) += cache-armv6.o
|
|||
obj-$(CONFIG_CPU_32v7) += cache-armv7.o
|
||||
obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o
|
||||
|
||||
pbl-y += start-pbl.o start-reset.o
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* start-pbl.c
|
||||
*
|
||||
* Copyright (c) 2010-2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
|
||||
* Copyright (c) 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <init.h>
|
||||
#include <asm/barebox-arm.h>
|
||||
#include <asm/barebox-arm-head.h>
|
||||
#include <asm-generic/memory_layout.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
void __naked __section(.text_head_entry) pbl_start(void)
|
||||
{
|
||||
barebox_arm_head();
|
||||
}
|
||||
|
||||
void barebox_pbl(uint32_t offset)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Board code can jump here by either returning from board_init_lowlevel
|
||||
* or by calling this function directly.
|
||||
*/
|
||||
void __naked __section(.text_ll_return) board_init_lowlevel_return(void)
|
||||
{
|
||||
uint32_t r, addr, offset;
|
||||
|
||||
/*
|
||||
* Get runtime address of this function. Do not
|
||||
* put any code above this.
|
||||
*/
|
||||
__asm__ __volatile__("1: adr %0, 1b":"=r"(addr));
|
||||
|
||||
/* Setup the stack */
|
||||
r = STACK_BASE + STACK_SIZE - 16;
|
||||
__asm__ __volatile__("mov sp, %0" : : "r"(r));
|
||||
|
||||
/* Get offset between linked address and runtime address */
|
||||
offset = (uint32_t)__ll_return - addr;
|
||||
|
||||
/* relocate to link address if necessary */
|
||||
if (offset)
|
||||
memcpy((void *)_text, (void *)(_text - offset),
|
||||
__bss_start - _text);
|
||||
|
||||
/* clear bss */
|
||||
memset(__bss_start, 0, __bss_stop - __bss_start);
|
||||
|
||||
/* flush I-cache before jumping to the copied binary */
|
||||
__asm__ __volatile__("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
|
||||
|
||||
r = (unsigned int)&barebox_pbl;
|
||||
/* call barebox_uncompress with its absolute address */
|
||||
__asm__ __volatile__(
|
||||
"mov r0, %1\n"
|
||||
"mov pc, %0\n"
|
||||
:
|
||||
: "r"(r), "r"(offset),
|
||||
: "r0");
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* start-reset.c
|
||||
*
|
||||
* Copyright (c) 2010 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <init.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/barebox-arm.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
/*
|
||||
* The actual reset vector. This code is position independent and usually
|
||||
* does not run at the address it's linked at.
|
||||
*/
|
||||
void __naked __bare_init reset(void)
|
||||
{
|
||||
uint32_t r;
|
||||
|
||||
/* set the cpu to SVC32 mode */
|
||||
__asm__ __volatile__("mrs %0, cpsr":"=r"(r));
|
||||
r &= ~0x1f;
|
||||
r |= 0xd3;
|
||||
__asm__ __volatile__("msr cpsr, %0" : : "r"(r));
|
||||
|
||||
#ifdef CONFIG_ARCH_HAS_LOWLEVEL_INIT
|
||||
arch_init_lowlevel();
|
||||
#endif
|
||||
|
||||
/* disable MMU stuff and caches */
|
||||
r = get_cr();
|
||||
r &= ~(CR_M | CR_C | CR_B | CR_S | CR_R | CR_V);
|
||||
r |= CR_I;
|
||||
|
||||
#if __LINUX_ARM_ARCH__ >= 6
|
||||
r |= CR_U;
|
||||
#else
|
||||
r |= CR_A;
|
||||
#endif
|
||||
|
||||
#ifdef __ARMEB__
|
||||
r |= CR_B;
|
||||
#endif
|
||||
set_cr(r);
|
||||
|
||||
#ifdef CONFIG_MACH_DO_LOWLEVEL_INIT
|
||||
board_init_lowlevel();
|
||||
#endif
|
||||
board_init_lowlevel_return();
|
||||
}
|
|
@ -24,55 +24,33 @@
|
|||
#include <init.h>
|
||||
#include <asm/barebox-arm.h>
|
||||
#include <asm/barebox-arm-head.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm-generic/memory_layout.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
#ifdef CONFIG_PBL_IMAGE
|
||||
/*
|
||||
* First function in the pbl image. We get here from
|
||||
* the pbl.
|
||||
*/
|
||||
void __naked __section(.text_entry) start(void)
|
||||
{
|
||||
u32 r;
|
||||
|
||||
/* Setup the stack */
|
||||
r = STACK_BASE + STACK_SIZE - 16;
|
||||
__asm__ __volatile__("mov sp, %0" : : "r"(r));
|
||||
/* clear bss */
|
||||
memset(__bss_start, 0, __bss_stop - __bss_start);
|
||||
|
||||
start_barebox();
|
||||
}
|
||||
#else
|
||||
|
||||
void __naked __section(.text_entry) start(void)
|
||||
{
|
||||
barebox_arm_head();
|
||||
}
|
||||
|
||||
/*
|
||||
* The actual reset vector. This code is position independent and usually
|
||||
* does not run at the address it's linked at.
|
||||
*/
|
||||
void __naked __bare_init reset(void)
|
||||
{
|
||||
uint32_t r;
|
||||
|
||||
/* set the cpu to SVC32 mode */
|
||||
__asm__ __volatile__("mrs %0, cpsr":"=r"(r));
|
||||
r &= ~0x1f;
|
||||
r |= 0xd3;
|
||||
__asm__ __volatile__("msr cpsr, %0" : : "r"(r));
|
||||
|
||||
#ifdef CONFIG_ARCH_HAS_LOWLEVEL_INIT
|
||||
arch_init_lowlevel();
|
||||
#endif
|
||||
|
||||
/* disable MMU stuff and caches */
|
||||
r = get_cr();
|
||||
r &= ~(CR_M | CR_C | CR_B | CR_S | CR_R | CR_V);
|
||||
r |= CR_I;
|
||||
|
||||
#if __LINUX_ARM_ARCH__ >= 6
|
||||
r |= CR_U;
|
||||
#else
|
||||
r |= CR_A;
|
||||
#endif
|
||||
|
||||
#ifdef __ARMEB__
|
||||
r |= CR_B;
|
||||
#endif
|
||||
set_cr(r);
|
||||
|
||||
#ifdef CONFIG_MACH_DO_LOWLEVEL_INIT
|
||||
board_init_lowlevel();
|
||||
#endif
|
||||
board_init_lowlevel_return();
|
||||
}
|
||||
|
||||
/*
|
||||
* Board code can jump here by either returning from board_init_lowlevel
|
||||
* or by calling this function directly.
|
||||
|
@ -109,4 +87,4 @@ void __naked __section(.text_ll_return) board_init_lowlevel_return(void)
|
|||
r = (unsigned int)&start_barebox;
|
||||
__asm__ __volatile__("mov pc, %0" : : "r"(r));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,3 +21,7 @@ obj-$(CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS) += memset.o
|
|||
obj-$(CONFIG_ARM_UNWIND) += unwind.o
|
||||
obj-$(CONFIG_MODULES) += module.o
|
||||
extra-y += barebox.lds
|
||||
|
||||
pbl-y += lib1funcs.o
|
||||
pbl-y += ashldi3.o
|
||||
pbl-y += div0.o
|
||||
|
|
|
@ -31,8 +31,9 @@ SECTIONS
|
|||
{
|
||||
. = TEXT_BASE;
|
||||
|
||||
#ifndef CONFIG_PBL_IMAGE
|
||||
PRE_IMAGE
|
||||
|
||||
#endif
|
||||
. = ALIGN(4);
|
||||
.text :
|
||||
{
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
OBJCOPYFLAGS_zbarebox.bin = -O binary
|
||||
|
||||
targets := zbarebox.lds zbarebox zbarebox.bin zbarebox.S
|
||||
|
||||
$(obj)/zbarebox.bin: $(obj)/zbarebox FORCE
|
||||
$(call if_changed,objcopy)
|
||||
$(call cmd,check_file_size,$(CONFIG_BAREBOX_MAX_IMAGE_SIZE))
|
||||
@echo ' Barebox: $@ is ready'
|
||||
|
||||
$(obj)/zbarebox.S: $(obj)/zbarebox FORCE
|
||||
$(call if_changed,disasm)
|
||||
|
||||
LDFLAGS_zbarebox := -Map zbarebox.map
|
||||
zbarebox-common := $(barebox-pbl-common)
|
||||
zbarebox-lds := $(obj)/zbarebox.lds
|
||||
|
||||
quiet_cmd_zbarebox__ ?= LD $@
|
||||
cmd_zbarebox__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_zbarebox) -o $@ \
|
||||
-T $(zbarebox-lds) \
|
||||
--start-group $(zbarebox-common) --end-group \
|
||||
$(filter-out $(zbarebox-lds) $(zbarebox-common) FORCE ,$^)
|
||||
|
||||
$(obj)/zbarebox: $(zbarebox-lds) $(zbarebox-common) FORCE
|
||||
$(call if_changed,zbarebox__)
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* (C) Copyright 2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
|
||||
*
|
||||
* See file CREDITS for list of people who contributed to this
|
||||
* project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||
* MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <asm-generic/barebox.lds.h>
|
||||
#include <asm-generic/memory_layout.h>
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(pbl_start)
|
||||
SECTIONS
|
||||
{
|
||||
. = HEAD_TEXT_BASE;
|
||||
|
||||
PRE_IMAGE
|
||||
|
||||
. = ALIGN(4);
|
||||
.text :
|
||||
{
|
||||
_stext = .;
|
||||
_text = .;
|
||||
*(.text_head_entry*)
|
||||
__ll_return = .;
|
||||
*(.text_ll_return*)
|
||||
__bare_init_start = .;
|
||||
*(.text_bare_init*)
|
||||
__bare_init_end = .;
|
||||
*(.text*)
|
||||
}
|
||||
BAREBOX_BARE_INIT_SIZE
|
||||
|
||||
. = ALIGN(4);
|
||||
.rodata : { *(.rodata*) }
|
||||
|
||||
_etext = .; /* End of text and rodata section */
|
||||
|
||||
. = ALIGN(4);
|
||||
.data : { *(.data*) }
|
||||
|
||||
. = ALIGN(4);
|
||||
__bss_start = .;
|
||||
.bss : { *(.bss*) }
|
||||
__bss_stop = .;
|
||||
_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
__piggydata_start = .;
|
||||
.piggydata : {
|
||||
*(.piggydata)
|
||||
}
|
||||
__piggydata_end = .;
|
||||
|
||||
_barebox_image_size = __piggydata_end - HEAD_TEXT_BASE;
|
||||
}
|
|
@ -101,6 +101,36 @@ config ENVIRONMENT_VARIABLES
|
|||
|
||||
menu "memory layout "
|
||||
|
||||
config HAVE_PBL_IMAGE
|
||||
bool
|
||||
|
||||
config HAVE_IMAGE_COMPRESSION
|
||||
bool
|
||||
|
||||
config PBL_IMAGE
|
||||
bool "Pre-Bootloader image"
|
||||
depends on HAVE_PBL_IMAGE
|
||||
|
||||
if PBL_IMAGE
|
||||
|
||||
config IMAGE_COMPRESSION
|
||||
bool "Compressed image"
|
||||
depends on HAVE_IMAGE_COMPRESSION
|
||||
|
||||
if IMAGE_COMPRESSION
|
||||
|
||||
choice
|
||||
prompt "Compression"
|
||||
|
||||
config IMAGE_COMPRESSION_LZO
|
||||
bool "lzo"
|
||||
|
||||
endchoice
|
||||
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
config MMU
|
||||
bool "Enable MMU"
|
||||
help
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#endif
|
||||
|
||||
#define HEAD_TEXT_BASE MALLOC_BASE
|
||||
#define MALLOC_SIZE CONFIG_MALLOC_SIZE
|
||||
#define STACK_SIZE CONFIG_STACK_SIZE
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
#
|
||||
# only unsed by the pbl
|
||||
#
|
||||
pbl-y += misc.o
|
||||
pbl-y += string.o
|
|
@ -0,0 +1,14 @@
|
|||
#include <common.h>
|
||||
#include <init.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/ctype.h>
|
||||
|
||||
void __noreturn panic(const char *fmt, ...)
|
||||
{
|
||||
while(1);
|
||||
}
|
||||
|
||||
void start_barebox(void)
|
||||
{
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* arch/arm/boot/compressed/string.c
|
||||
*
|
||||
* Small subset of simple string routines
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
void *memcpy(void *__dest, __const void *__src, size_t __n)
|
||||
{
|
||||
int i = 0;
|
||||
unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
|
||||
|
||||
for (i = __n >> 3; i > 0; i--) {
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
if (__n & 1 << 2) {
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
if (__n & 1 << 1) {
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
}
|
||||
|
||||
if (__n & 1)
|
||||
*d++ = *s++;
|
||||
|
||||
return __dest;
|
||||
}
|
||||
|
||||
void *memmove(void *__dest, __const void *__src, size_t count)
|
||||
{
|
||||
unsigned char *d = __dest;
|
||||
const unsigned char *s = __src;
|
||||
|
||||
if (__dest == __src)
|
||||
return __dest;
|
||||
|
||||
if (__dest < __src)
|
||||
return memcpy(__dest, __src, count);
|
||||
|
||||
while (count--)
|
||||
d[count] = s[count];
|
||||
return __dest;
|
||||
}
|
||||
|
||||
size_t strlen(const char *s)
|
||||
{
|
||||
const char *sc = s;
|
||||
|
||||
while (*sc != '\0')
|
||||
sc++;
|
||||
return sc - s;
|
||||
}
|
||||
|
||||
int memcmp(const void *cs, const void *ct, size_t count)
|
||||
{
|
||||
const unsigned char *su1 = cs, *su2 = ct, *end = su1 + count;
|
||||
int res = 0;
|
||||
|
||||
while (su1 < end) {
|
||||
res = *su1++ - *su2++;
|
||||
if (res)
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int strcmp(const char *cs, const char *ct)
|
||||
{
|
||||
unsigned char c1, c2;
|
||||
int res = 0;
|
||||
|
||||
do {
|
||||
c1 = *cs++;
|
||||
c2 = *ct++;
|
||||
res = c1 - c2;
|
||||
if (res)
|
||||
break;
|
||||
} while (c1);
|
||||
return res;
|
||||
}
|
||||
|
||||
void *memchr(const void *s, int c, size_t count)
|
||||
{
|
||||
const unsigned char *p = s;
|
||||
|
||||
while (count--)
|
||||
if ((unsigned char)c == *p++)
|
||||
return (void *)(p - 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *strchr(const char *s, int c)
|
||||
{
|
||||
while (*s != (char)c)
|
||||
if (*s++ == '\0')
|
||||
return NULL;
|
||||
return (char *)s;
|
||||
}
|
||||
|
||||
#undef memset
|
||||
|
||||
void *memset(void *s, int c, size_t count)
|
||||
{
|
||||
char *xs = s;
|
||||
while (count--)
|
||||
*xs++ = c;
|
||||
return s;
|
||||
}
|
||||
|
||||
void __memzero(void *s, size_t count)
|
||||
{
|
||||
memset(s, 0, count);
|
||||
}
|
Loading…
Reference in New Issue