mirror of
git://projects.qi-hardware.com/xburst-tools.git
synced 2024-11-01 10:22:48 +02:00
add-kernel-init.patch
Huge patch boils down massive kernel image parsing and boot action to a modest sequence of code that actually boots the kernel. Signed-off-by: Andy Green <andy@openmoko.com>
This commit is contained in:
parent
b44cb06c6b
commit
5a494607f0
@ -25,8 +25,9 @@ BUILD_VERSION := ${BUILD_BRANCH}_${BUILD_HEAD}
|
||||
LDS = src/kboot-stage1.lds
|
||||
INCLUDE = include
|
||||
IMAGE_DIR = image
|
||||
CFLAGS = -Wall -Werror -fno-builtin -ffreestanding -fno-strict-aliasing \
|
||||
-fno-common -ffixed-r8 -I $(INCLUDE) -g -c \
|
||||
CFLAGS = -Wall -Werror -I $(INCLUDE) -g -c -O2 -fno-strict-aliasing \
|
||||
-fno-common -ffixed-r8 -msoft-float -fno-builtin -ffreestanding \
|
||||
-march=armv4t -mno-thumb-interwork -Wstrict-prototypes \
|
||||
-DBUILD_HOST="${BUILD_HOST}" -DBUILD_VERSION="${BUILD_VERSION}" \
|
||||
-DBUILD_DATE="${BUILD_DATE}"
|
||||
LDFLAGS =
|
||||
|
572
qiboot/include/image.h
Normal file
572
qiboot/include/image.h
Normal file
@ -0,0 +1,572 @@
|
||||
/*
|
||||
* (C) Copyright 2008 Semihalf
|
||||
*
|
||||
* (C) Copyright 2000-2005
|
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
********************************************************************
|
||||
* NOTE: This header file defines an interface to U-Boot. Including
|
||||
* this (unmodified) header file in another file is considered normal
|
||||
* use of U-Boot, and does *not* fall under the heading of "derived
|
||||
* work".
|
||||
********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __IMAGE_H__
|
||||
#define __IMAGE_H__
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/*
|
||||
* Operating System Codes
|
||||
*/
|
||||
#define IH_OS_INVALID 0 /* Invalid OS */
|
||||
#define IH_OS_OPENBSD 1 /* OpenBSD */
|
||||
#define IH_OS_NETBSD 2 /* NetBSD */
|
||||
#define IH_OS_FREEBSD 3 /* FreeBSD */
|
||||
#define IH_OS_4_4BSD 4 /* 4.4BSD */
|
||||
#define IH_OS_LINUX 5 /* Linux */
|
||||
#define IH_OS_SVR4 6 /* SVR4 */
|
||||
#define IH_OS_ESIX 7 /* Esix */
|
||||
#define IH_OS_SOLARIS 8 /* Solaris */
|
||||
#define IH_OS_IRIX 9 /* Irix */
|
||||
#define IH_OS_SCO 10 /* SCO */
|
||||
#define IH_OS_DELL 11 /* Dell */
|
||||
#define IH_OS_NCR 12 /* NCR */
|
||||
#define IH_OS_LYNXOS 13 /* LynxOS */
|
||||
#define IH_OS_VXWORKS 14 /* VxWorks */
|
||||
#define IH_OS_PSOS 15 /* pSOS */
|
||||
#define IH_OS_QNX 16 /* QNX */
|
||||
#define IH_OS_U_BOOT 17 /* Firmware */
|
||||
#define IH_OS_RTEMS 18 /* RTEMS */
|
||||
#define IH_OS_ARTOS 19 /* ARTOS */
|
||||
#define IH_OS_UNITY 20 /* Unity OS */
|
||||
|
||||
/*
|
||||
* CPU Architecture Codes (supported by Linux)
|
||||
*/
|
||||
#define IH_ARCH_INVALID 0 /* Invalid CPU */
|
||||
#define IH_ARCH_ALPHA 1 /* Alpha */
|
||||
#define IH_ARCH_ARM 2 /* ARM */
|
||||
#define IH_ARCH_I386 3 /* Intel x86 */
|
||||
#define IH_ARCH_IA64 4 /* IA64 */
|
||||
#define IH_ARCH_MIPS 5 /* MIPS */
|
||||
#define IH_ARCH_MIPS64 6 /* MIPS 64 Bit */
|
||||
#define IH_ARCH_PPC 7 /* PowerPC */
|
||||
#define IH_ARCH_S390 8 /* IBM S390 */
|
||||
#define IH_ARCH_SH 9 /* SuperH */
|
||||
#define IH_ARCH_SPARC 10 /* Sparc */
|
||||
#define IH_ARCH_SPARC64 11 /* Sparc 64 Bit */
|
||||
#define IH_ARCH_M68K 12 /* M68K */
|
||||
#define IH_ARCH_NIOS 13 /* Nios-32 */
|
||||
#define IH_ARCH_MICROBLAZE 14 /* MicroBlaze */
|
||||
#define IH_ARCH_NIOS2 15 /* Nios-II */
|
||||
#define IH_ARCH_BLACKFIN 16 /* Blackfin */
|
||||
#define IH_ARCH_AVR32 17 /* AVR32 */
|
||||
#define IH_ARCH_ST200 18 /* STMicroelectronics ST200 */
|
||||
|
||||
/*
|
||||
* Image Types
|
||||
*
|
||||
* "Standalone Programs" are directly runnable in the environment
|
||||
* provided by U-Boot; it is expected that (if they behave
|
||||
* well) you can continue to work in U-Boot after return from
|
||||
* the Standalone Program.
|
||||
* "OS Kernel Images" are usually images of some Embedded OS which
|
||||
* will take over control completely. Usually these programs
|
||||
* will install their own set of exception handlers, device
|
||||
* drivers, set up the MMU, etc. - this means, that you cannot
|
||||
* expect to re-enter U-Boot except by resetting the CPU.
|
||||
* "RAMDisk Images" are more or less just data blocks, and their
|
||||
* parameters (address, size) are passed to an OS kernel that is
|
||||
* being started.
|
||||
* "Multi-File Images" contain several images, typically an OS
|
||||
* (Linux) kernel image and one or more data images like
|
||||
* RAMDisks. This construct is useful for instance when you want
|
||||
* to boot over the network using BOOTP etc., where the boot
|
||||
* server provides just a single image file, but you want to get
|
||||
* for instance an OS kernel and a RAMDisk image.
|
||||
*
|
||||
* "Multi-File Images" start with a list of image sizes, each
|
||||
* image size (in bytes) specified by an "uint32_t" in network
|
||||
* byte order. This list is terminated by an "(uint32_t)0".
|
||||
* Immediately after the terminating 0 follow the images, one by
|
||||
* one, all aligned on "uint32_t" boundaries (size rounded up to
|
||||
* a multiple of 4 bytes - except for the last file).
|
||||
*
|
||||
* "Firmware Images" are binary images containing firmware (like
|
||||
* U-Boot or FPGA images) which usually will be programmed to
|
||||
* flash memory.
|
||||
*
|
||||
* "Script files" are command sequences that will be executed by
|
||||
* U-Boot's command interpreter; this feature is especially
|
||||
* useful when you configure U-Boot to use a real shell (hush)
|
||||
* as command interpreter (=> Shell Scripts).
|
||||
*/
|
||||
|
||||
#define IH_TYPE_INVALID 0 /* Invalid Image */
|
||||
#define IH_TYPE_STANDALONE 1 /* Standalone Program */
|
||||
#define IH_TYPE_KERNEL 2 /* OS Kernel Image */
|
||||
#define IH_TYPE_RAMDISK 3 /* RAMDisk Image */
|
||||
#define IH_TYPE_MULTI 4 /* Multi-File Image */
|
||||
#define IH_TYPE_FIRMWARE 5 /* Firmware Image */
|
||||
#define IH_TYPE_SCRIPT 6 /* Script file */
|
||||
#define IH_TYPE_FILESYSTEM 7 /* Filesystem Image (any type) */
|
||||
#define IH_TYPE_FLATDT 8 /* Binary Flat Device Tree Blob */
|
||||
|
||||
/*
|
||||
* Compression Types
|
||||
*/
|
||||
#define IH_COMP_NONE 0 /* No Compression Used */
|
||||
#define IH_COMP_GZIP 1 /* gzip Compression Used */
|
||||
#define IH_COMP_BZIP2 2 /* bzip2 Compression Used */
|
||||
|
||||
#define IH_MAGIC 0x27051956 /* Image Magic Number */
|
||||
#define IH_NMLEN 32 /* Image Name Length */
|
||||
|
||||
/*
|
||||
* Legacy format image header,
|
||||
* all data in network byte order (aka natural aka bigendian).
|
||||
*/
|
||||
typedef struct image_header {
|
||||
uint32_t ih_magic; /* Image Header Magic Number */
|
||||
uint32_t ih_hcrc; /* Image Header CRC Checksum */
|
||||
uint32_t ih_time; /* Image Creation Timestamp */
|
||||
uint32_t ih_size; /* Image Data Size */
|
||||
uint32_t ih_load; /* Data Load Address */
|
||||
uint32_t ih_ep; /* Entry Point Address */
|
||||
uint32_t ih_dcrc; /* Image Data CRC Checksum */
|
||||
uint8_t ih_os; /* Operating System */
|
||||
uint8_t ih_arch; /* CPU architecture */
|
||||
uint8_t ih_type; /* Image Type */
|
||||
uint8_t ih_comp; /* Compression Type */
|
||||
uint8_t ih_name[IH_NMLEN]; /* Image Name */
|
||||
} image_header_t;
|
||||
|
||||
/*
|
||||
* Legacy and FIT format headers used by do_bootm() and do_bootm_<os>()
|
||||
* routines.
|
||||
*/
|
||||
typedef struct bootm_headers {
|
||||
/*
|
||||
* Legacy os image header, if it is a multi component image
|
||||
* then boot_get_ramdisk() and get_fdt() will attempt to get
|
||||
* data from second and third component accordingly.
|
||||
*/
|
||||
image_header_t *legacy_hdr_os;
|
||||
ulong legacy_hdr_valid;
|
||||
|
||||
#if defined(CONFIG_FIT)
|
||||
const char *fit_uname_cfg; /* configuration node unit name */
|
||||
|
||||
void *fit_hdr_os; /* os FIT image header */
|
||||
const char *fit_uname_os; /* os subimage node unit name */
|
||||
int fit_noffset_os; /* os subimage node offset */
|
||||
|
||||
void *fit_hdr_rd; /* init ramdisk FIT image header */
|
||||
const char *fit_uname_rd; /* init ramdisk subimage node unit name */
|
||||
int fit_noffset_rd; /* init ramdisk subimage node offset */
|
||||
|
||||
#if defined(CONFIG_PPC)
|
||||
void *fit_hdr_fdt; /* FDT blob FIT image header */
|
||||
const char *fit_uname_fdt; /* FDT blob subimage node unit name */
|
||||
int fit_noffset_fdt;/* FDT blob subimage node offset */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int verify; /* getenv("verify")[0] != 'n' */
|
||||
int autostart; /* getenv("autostart")[0] != 'n' */
|
||||
struct lmb *lmb; /* for memory mgmt */
|
||||
} bootm_headers_t;
|
||||
|
||||
/*
|
||||
* Some systems (for example LWMON) have very short watchdog periods;
|
||||
* we must make sure to split long operations like memmove() or
|
||||
* crc32() into reasonable chunks.
|
||||
*/
|
||||
#define CHUNKSZ (64 * 1024)
|
||||
|
||||
#define uimage_to_cpu(x) ntohl(x)
|
||||
#define cpu_to_uimage(x) htonl(x)
|
||||
|
||||
const char *genimg_get_os_name (uint8_t os);
|
||||
const char *genimg_get_arch_name (uint8_t arch);
|
||||
const char *genimg_get_type_name (uint8_t type);
|
||||
const char *genimg_get_comp_name (uint8_t comp);
|
||||
int genimg_get_os_id (const char *name);
|
||||
int genimg_get_arch_id (const char *name);
|
||||
int genimg_get_type_id (const char *name);
|
||||
int genimg_get_comp_id (const char *name);
|
||||
|
||||
#ifndef USE_HOSTCC
|
||||
/* Image format types, returned by _get_format() routine */
|
||||
#define IMAGE_FORMAT_INVALID 0x00
|
||||
#define IMAGE_FORMAT_LEGACY 0x01 /* legacy image_header based format */
|
||||
#define IMAGE_FORMAT_FIT 0x02 /* new, libfdt based format */
|
||||
|
||||
int genimg_get_format (void *img_addr);
|
||||
int genimg_has_config (bootm_headers_t *images);
|
||||
ulong genimg_get_image (ulong img_addr);
|
||||
|
||||
int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images,
|
||||
uint8_t arch, ulong *rd_start, ulong *rd_end);
|
||||
|
||||
#if defined(CONFIG_PPC) || defined(CONFIG_M68K)
|
||||
int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len,
|
||||
ulong *initrd_start, ulong *initrd_end);
|
||||
|
||||
int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end,
|
||||
ulong bootmap_base);
|
||||
int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base);
|
||||
#endif /* CONFIG_PPC || CONFIG_M68K */
|
||||
#endif /* !USE_HOSTCC */
|
||||
|
||||
/*******************************************************************/
|
||||
/* Legacy format specific code (prefixed with image_) */
|
||||
/*******************************************************************/
|
||||
static inline uint32_t image_get_header_size (void)
|
||||
{
|
||||
return (sizeof (image_header_t));
|
||||
}
|
||||
|
||||
#define image_get_hdr_l(f) \
|
||||
static inline uint32_t image_get_##f(image_header_t *hdr) \
|
||||
{ \
|
||||
return uimage_to_cpu (hdr->ih_##f); \
|
||||
}
|
||||
image_get_hdr_l (magic);
|
||||
image_get_hdr_l (hcrc);
|
||||
image_get_hdr_l (time);
|
||||
image_get_hdr_l (size);
|
||||
image_get_hdr_l (load);
|
||||
image_get_hdr_l (ep);
|
||||
image_get_hdr_l (dcrc);
|
||||
|
||||
#define image_get_hdr_b(f) \
|
||||
static inline uint8_t image_get_##f(image_header_t *hdr) \
|
||||
{ \
|
||||
return hdr->ih_##f; \
|
||||
}
|
||||
image_get_hdr_b (os);
|
||||
image_get_hdr_b (arch);
|
||||
image_get_hdr_b (type);
|
||||
image_get_hdr_b (comp);
|
||||
|
||||
static inline char *image_get_name (image_header_t *hdr)
|
||||
{
|
||||
return (char *)hdr->ih_name;
|
||||
}
|
||||
|
||||
static inline uint32_t image_get_data_size (image_header_t *hdr)
|
||||
{
|
||||
return image_get_size (hdr);
|
||||
}
|
||||
|
||||
/**
|
||||
* image_get_data - get image payload start address
|
||||
* @hdr: image header
|
||||
*
|
||||
* image_get_data() returns address of the image payload. For single
|
||||
* component images it is image data start. For multi component
|
||||
* images it points to the null terminated table of sub-images sizes.
|
||||
*
|
||||
* returns:
|
||||
* image payload data start address
|
||||
*/
|
||||
static inline ulong image_get_data (image_header_t *hdr)
|
||||
{
|
||||
return ((ulong)hdr + image_get_header_size ());
|
||||
}
|
||||
|
||||
static inline uint32_t image_get_image_size (image_header_t *hdr)
|
||||
{
|
||||
return (image_get_size (hdr) + image_get_header_size ());
|
||||
}
|
||||
static inline ulong image_get_image_end (image_header_t *hdr)
|
||||
{
|
||||
return ((ulong)hdr + image_get_image_size (hdr));
|
||||
}
|
||||
|
||||
#define image_set_hdr_l(f) \
|
||||
static inline void image_set_##f(image_header_t *hdr, uint32_t val) \
|
||||
{ \
|
||||
hdr->ih_##f = cpu_to_uimage (val); \
|
||||
}
|
||||
image_set_hdr_l (magic);
|
||||
image_set_hdr_l (hcrc);
|
||||
image_set_hdr_l (time);
|
||||
image_set_hdr_l (size);
|
||||
image_set_hdr_l (load);
|
||||
image_set_hdr_l (ep);
|
||||
image_set_hdr_l (dcrc);
|
||||
|
||||
#define image_set_hdr_b(f) \
|
||||
static inline void image_set_##f(image_header_t *hdr, uint8_t val) \
|
||||
{ \
|
||||
hdr->ih_##f = val; \
|
||||
}
|
||||
image_set_hdr_b (os);
|
||||
image_set_hdr_b (arch);
|
||||
image_set_hdr_b (type);
|
||||
image_set_hdr_b (comp);
|
||||
|
||||
static inline void image_set_name (image_header_t *hdr, const char *name)
|
||||
{
|
||||
strncpy (image_get_name (hdr), name, IH_NMLEN);
|
||||
}
|
||||
|
||||
int image_check_hcrc (image_header_t *hdr);
|
||||
int image_check_dcrc (image_header_t *hdr);
|
||||
#ifndef USE_HOSTCC
|
||||
int image_check_dcrc_wd (image_header_t *hdr, ulong chunksize);
|
||||
int getenv_verify (void);
|
||||
int getenv_autostart (void);
|
||||
ulong getenv_bootm_low(void);
|
||||
ulong getenv_bootm_size(void);
|
||||
void memmove_wd (void *to, void *from, size_t len, ulong chunksz);
|
||||
#endif
|
||||
|
||||
static inline int image_check_magic (image_header_t *hdr)
|
||||
{
|
||||
return (image_get_magic (hdr) == IH_MAGIC);
|
||||
}
|
||||
static inline int image_check_type (image_header_t *hdr, uint8_t type)
|
||||
{
|
||||
return (image_get_type (hdr) == type);
|
||||
}
|
||||
static inline int image_check_arch (image_header_t *hdr, uint8_t arch)
|
||||
{
|
||||
return (image_get_arch (hdr) == arch);
|
||||
}
|
||||
static inline int image_check_os (image_header_t *hdr, uint8_t os)
|
||||
{
|
||||
return (image_get_os (hdr) == os);
|
||||
}
|
||||
|
||||
ulong image_multi_count (image_header_t *hdr);
|
||||
void image_multi_getimg (image_header_t *hdr, ulong idx,
|
||||
ulong *data, ulong *len);
|
||||
|
||||
inline void image_print_contents (image_header_t *hdr);
|
||||
inline void image_print_contents_noindent (image_header_t *hdr);
|
||||
|
||||
#ifndef USE_HOSTCC
|
||||
static inline int image_check_target_arch (image_header_t *hdr)
|
||||
{
|
||||
#if defined(__ARM__)
|
||||
if (!image_check_arch (hdr, IH_ARCH_ARM))
|
||||
#elif defined(__avr32__)
|
||||
if (!image_check_arch (hdr, IH_ARCH_AVR32))
|
||||
#elif defined(__bfin__)
|
||||
if (!image_check_arch (hdr, IH_ARCH_BLACKFIN))
|
||||
#elif defined(__I386__)
|
||||
if (!image_check_arch (hdr, IH_ARCH_I386))
|
||||
#elif defined(__M68K__)
|
||||
if (!image_check_arch (hdr, IH_ARCH_M68K))
|
||||
#elif defined(__microblaze__)
|
||||
if (!image_check_arch (hdr, IH_ARCH_MICROBLAZE))
|
||||
#elif defined(__mips__)
|
||||
if (!image_check_arch (hdr, IH_ARCH_MIPS))
|
||||
#elif defined(__nios__)
|
||||
if (!image_check_arch (hdr, IH_ARCH_NIOS))
|
||||
#elif defined(__nios2__)
|
||||
if (!image_check_arch (hdr, IH_ARCH_NIOS2))
|
||||
#elif defined(__PPC__)
|
||||
if (!image_check_arch (hdr, IH_ARCH_PPC))
|
||||
#elif defined(__sh__)
|
||||
if (!image_check_arch (hdr, IH_ARCH_SH))
|
||||
#else
|
||||
# error Unknown CPU type
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif /* USE_HOSTCC */
|
||||
|
||||
/*******************************************************************/
|
||||
/* New uImage format specific code (prefixed with fit_) */
|
||||
/*******************************************************************/
|
||||
#if defined(CONFIG_FIT)
|
||||
|
||||
#define FIT_IMAGES_PATH "/images"
|
||||
#define FIT_CONFS_PATH "/configurations"
|
||||
|
||||
/* hash node */
|
||||
#define FIT_HASH_NODENAME "hash"
|
||||
#define FIT_ALGO_PROP "algo"
|
||||
#define FIT_VALUE_PROP "value"
|
||||
|
||||
/* image node */
|
||||
#define FIT_DATA_PROP "data"
|
||||
#define FIT_TIMESTAMP_PROP "timestamp"
|
||||
#define FIT_DESC_PROP "description"
|
||||
#define FIT_ARCH_PROP "arch"
|
||||
#define FIT_TYPE_PROP "type"
|
||||
#define FIT_OS_PROP "os"
|
||||
#define FIT_COMP_PROP "compression"
|
||||
#define FIT_ENTRY_PROP "entry"
|
||||
#define FIT_LOAD_PROP "load"
|
||||
|
||||
/* configuration node */
|
||||
#define FIT_KERNEL_PROP "kernel"
|
||||
#define FIT_RAMDISK_PROP "ramdisk"
|
||||
#define FIT_FDT_PROP "fdt"
|
||||
#define FIT_DEFAULT_PROP "default"
|
||||
|
||||
#define FIT_MAX_HASH_LEN 20 /* max(crc32_len(4), sha1_len(20)) */
|
||||
|
||||
/* cmdline argument format parsing */
|
||||
inline int fit_parse_conf (const char *spec, ulong addr_curr,
|
||||
ulong *addr, const char **conf_name);
|
||||
inline int fit_parse_subimage (const char *spec, ulong addr_curr,
|
||||
ulong *addr, const char **image_name);
|
||||
|
||||
inline void fit_print_contents (const void *fit);
|
||||
inline void fit_print_contents_noindent (const void *fit);
|
||||
void fit_image_print (const void *fit, int noffset, const char *p);
|
||||
void fit_image_print_hash (const void *fit, int noffset, const char *p);
|
||||
|
||||
/**
|
||||
* fit_get_end - get FIT image size
|
||||
* @fit: pointer to the FIT format image header
|
||||
*
|
||||
* returns:
|
||||
* size of the FIT image (blob) in memory
|
||||
*/
|
||||
static inline ulong fit_get_size (const void *fit)
|
||||
{
|
||||
return fdt_totalsize (fit);
|
||||
}
|
||||
|
||||
/**
|
||||
* fit_get_end - get FIT image end
|
||||
* @fit: pointer to the FIT format image header
|
||||
*
|
||||
* returns:
|
||||
* end address of the FIT image (blob) in memory
|
||||
*/
|
||||
static inline ulong fit_get_end (const void *fit)
|
||||
{
|
||||
return (ulong)fit + fdt_totalsize (fit);
|
||||
}
|
||||
|
||||
/**
|
||||
* fit_get_name - get FIT node name
|
||||
* @fit: pointer to the FIT format image header
|
||||
*
|
||||
* returns:
|
||||
* NULL, on error
|
||||
* pointer to node name, on success
|
||||
*/
|
||||
static inline const char *fit_get_name (const void *fit_hdr,
|
||||
int noffset, int *len)
|
||||
{
|
||||
return fdt_get_name (fit_hdr, noffset, len);
|
||||
}
|
||||
|
||||
int fit_get_desc (const void *fit, int noffset, char **desc);
|
||||
int fit_get_timestamp (const void *fit, int noffset, time_t *timestamp);
|
||||
|
||||
int fit_image_get_node (const void *fit, const char *image_uname);
|
||||
int fit_image_get_os (const void *fit, int noffset, uint8_t *os);
|
||||
int fit_image_get_arch (const void *fit, int noffset, uint8_t *arch);
|
||||
int fit_image_get_type (const void *fit, int noffset, uint8_t *type);
|
||||
int fit_image_get_comp (const void *fit, int noffset, uint8_t *comp);
|
||||
int fit_image_get_load (const void *fit, int noffset, ulong *load);
|
||||
int fit_image_get_entry (const void *fit, int noffset, ulong *entry);
|
||||
int fit_image_get_data (const void *fit, int noffset,
|
||||
const void **data, size_t *size);
|
||||
|
||||
int fit_image_hash_get_algo (const void *fit, int noffset, char **algo);
|
||||
int fit_image_hash_get_value (const void *fit, int noffset, uint8_t **value,
|
||||
int *value_len);
|
||||
|
||||
int fit_set_timestamp (void *fit, int noffset, time_t timestamp);
|
||||
int fit_set_hashes (void *fit);
|
||||
int fit_image_set_hashes (void *fit, int image_noffset);
|
||||
int fit_image_hash_set_value (void *fit, int noffset, uint8_t *value,
|
||||
int value_len);
|
||||
|
||||
int fit_image_check_hashes (const void *fit, int noffset);
|
||||
int fit_image_check_os (const void *fit, int noffset, uint8_t os);
|
||||
int fit_image_check_arch (const void *fit, int noffset, uint8_t arch);
|
||||
int fit_image_check_type (const void *fit, int noffset, uint8_t type);
|
||||
int fit_image_check_comp (const void *fit, int noffset, uint8_t comp);
|
||||
int fit_check_format (const void *fit);
|
||||
|
||||
int fit_conf_get_node (const void *fit, const char *conf_uname);
|
||||
int fit_conf_get_kernel_node (const void *fit, int noffset);
|
||||
int fit_conf_get_ramdisk_node (const void *fit, int noffset);
|
||||
int fit_conf_get_fdt_node (const void *fit, int noffset);
|
||||
|
||||
void fit_conf_print (const void *fit, int noffset, const char *p);
|
||||
|
||||
#ifndef USE_HOSTCC
|
||||
static inline int fit_image_check_target_arch (const void *fdt, int node)
|
||||
{
|
||||
#if defined(__ARM__)
|
||||
if (!fit_image_check_arch (fdt, node, IH_ARCH_ARM))
|
||||
#elif defined(__avr32__)
|
||||
if (!fit_image_check_arch (fdt, node, IH_ARCH_AVR32))
|
||||
#elif defined(__bfin__)
|
||||
if (!fit_image_check_arch (fdt, node, IH_ARCH_BLACKFIN))
|
||||
#elif defined(__I386__)
|
||||
if (!fit_image_check_arch (fdt, node, IH_ARCH_I386))
|
||||
#elif defined(__M68K__)
|
||||
if (!fit_image_check_arch (fdt, node, IH_ARCH_M68K))
|
||||
#elif defined(__microblaze__)
|
||||
if (!fit_image_check_arch (fdt, node, IH_ARCH_MICROBLAZE))
|
||||
#elif defined(__mips__)
|
||||
if (!fit_image_check_arch (fdt, node, IH_ARCH_MIPS))
|
||||
#elif defined(__nios__)
|
||||
if (!fit_image_check_arch (fdt, node, IH_ARCH_NIOS))
|
||||
#elif defined(__nios2__)
|
||||
if (!fit_image_check_arch (fdt, node, IH_ARCH_NIOS2))
|
||||
#elif defined(__PPC__)
|
||||
if (!fit_image_check_arch (fdt, node, IH_ARCH_PPC))
|
||||
#elif defined(__sh__)
|
||||
if (!fit_image_check_arch (fdt, node, IH_ARCH_SH))
|
||||
#else
|
||||
# error Unknown CPU type
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif /* USE_HOSTCC */
|
||||
|
||||
#ifdef CONFIG_FIT_VERBOSE
|
||||
#define fit_unsupported(msg) printf ("! %s:%d " \
|
||||
"FIT images not supported for '%s'\n", \
|
||||
__FILE__, __LINE__, (msg))
|
||||
|
||||
#define fit_unsupported_reset(msg) printf ("! %s:%d " \
|
||||
"FIT images not supported for '%s' " \
|
||||
"- must reset board to recover!\n", \
|
||||
__FILE__, __LINE__, (msg))
|
||||
#else
|
||||
#define fit_unsupported(msg)
|
||||
#define fit_unsupported_reset(msg)
|
||||
#endif /* CONFIG_FIT_VERBOSE */
|
||||
#endif /* CONFIG_FIT */
|
||||
|
||||
#endif /* __IMAGE_H__ */
|
@ -107,7 +107,6 @@ void port_init(void);
|
||||
void serial_init (const int ubrdiv_val,const int uart);
|
||||
void serial_putc (const int uart,const char c);
|
||||
int printk(const char *fmt, ...);
|
||||
int vsprintf(char *buf, const char *fmt, va_list args);
|
||||
int puts(const char *string);
|
||||
|
||||
#endif
|
||||
|
269
qiboot/include/setup.h
Normal file
269
qiboot/include/setup.h
Normal file
@ -0,0 +1,269 @@
|
||||
/*
|
||||
* linux/include/asm/setup.h
|
||||
*
|
||||
* Copyright (C) 1997-1999 Russell King
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Structure passed to kernel to tell it about the
|
||||
* hardware it's running on. See linux/Documentation/arm/Setup
|
||||
* for more info.
|
||||
*
|
||||
* NOTE:
|
||||
* This file contains two ways to pass information from the boot
|
||||
* loader to the kernel. The old struct param_struct is deprecated,
|
||||
* but it will be kept in the kernel for 5 years from now
|
||||
* (2001). This will allow boot loaders to convert to the new struct
|
||||
* tag way.
|
||||
*/
|
||||
#ifndef __ASMARM_SETUP_H
|
||||
#define __ASMARM_SETUP_H
|
||||
|
||||
/*
|
||||
* Usage:
|
||||
* - do not go blindly adding fields, add them at the end
|
||||
* - when adding fields, don't rely on the address until
|
||||
* a patch from me has been released
|
||||
* - unused fields should be zero (for future expansion)
|
||||
* - this structure is relatively short-lived - only
|
||||
* guaranteed to contain useful data in setup_arch()
|
||||
*/
|
||||
#define COMMAND_LINE_SIZE 1024
|
||||
|
||||
/* This is the old deprecated way to pass parameters to the kernel */
|
||||
struct param_struct {
|
||||
union {
|
||||
struct {
|
||||
unsigned long page_size; /* 0 */
|
||||
unsigned long nr_pages; /* 4 */
|
||||
unsigned long ramdisk_size; /* 8 */
|
||||
unsigned long flags; /* 12 */
|
||||
#define FLAG_READONLY 1
|
||||
#define FLAG_RDLOAD 4
|
||||
#define FLAG_RDPROMPT 8
|
||||
unsigned long rootdev; /* 16 */
|
||||
unsigned long video_num_cols; /* 20 */
|
||||
unsigned long video_num_rows; /* 24 */
|
||||
unsigned long video_x; /* 28 */
|
||||
unsigned long video_y; /* 32 */
|
||||
unsigned long memc_control_reg; /* 36 */
|
||||
unsigned char sounddefault; /* 40 */
|
||||
unsigned char adfsdrives; /* 41 */
|
||||
unsigned char bytes_per_char_h; /* 42 */
|
||||
unsigned char bytes_per_char_v; /* 43 */
|
||||
unsigned long pages_in_bank[4]; /* 44 */
|
||||
unsigned long pages_in_vram; /* 60 */
|
||||
unsigned long initrd_start; /* 64 */
|
||||
unsigned long initrd_size; /* 68 */
|
||||
unsigned long rd_start; /* 72 */
|
||||
unsigned long system_rev; /* 76 */
|
||||
unsigned long system_serial_low; /* 80 */
|
||||
unsigned long system_serial_high; /* 84 */
|
||||
unsigned long mem_fclk_21285; /* 88 */
|
||||
} s;
|
||||
char unused[256];
|
||||
} u1;
|
||||
union {
|
||||
char paths[8][128];
|
||||
struct {
|
||||
unsigned long magic;
|
||||
char n[1024 - sizeof(unsigned long)];
|
||||
} s;
|
||||
} u2;
|
||||
char commandline[COMMAND_LINE_SIZE];
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* The new way of passing information: a list of tagged entries
|
||||
*/
|
||||
|
||||
/* The list ends with an ATAG_NONE node. */
|
||||
#define ATAG_NONE 0x00000000
|
||||
|
||||
struct tag_header {
|
||||
u32 size;
|
||||
u32 tag;
|
||||
};
|
||||
|
||||
/* The list must start with an ATAG_CORE node */
|
||||
#define ATAG_CORE 0x54410001
|
||||
|
||||
struct tag_core {
|
||||
u32 flags; /* bit 0 = read-only */
|
||||
u32 pagesize;
|
||||
u32 rootdev;
|
||||
};
|
||||
|
||||
/* it is allowed to have multiple ATAG_MEM nodes */
|
||||
#define ATAG_MEM 0x54410002
|
||||
|
||||
struct tag_mem32 {
|
||||
u32 size;
|
||||
u32 start; /* physical start address */
|
||||
};
|
||||
|
||||
/* VGA text type displays */
|
||||
#define ATAG_VIDEOTEXT 0x54410003
|
||||
|
||||
struct tag_videotext {
|
||||
u8 x;
|
||||
u8 y;
|
||||
u16 video_page;
|
||||
u8 video_mode;
|
||||
u8 video_cols;
|
||||
u16 video_ega_bx;
|
||||
u8 video_lines;
|
||||
u8 video_isvga;
|
||||
u16 video_points;
|
||||
};
|
||||
|
||||
/* describes how the ramdisk will be used in kernel */
|
||||
#define ATAG_RAMDISK 0x54410004
|
||||
|
||||
struct tag_ramdisk {
|
||||
u32 flags; /* bit 0 = load, bit 1 = prompt */
|
||||
u32 size; /* decompressed ramdisk size in _kilo_ bytes */
|
||||
u32 start; /* starting block of floppy-based RAM disk image */
|
||||
};
|
||||
|
||||
/* describes where the compressed ramdisk image lives (virtual address) */
|
||||
/*
|
||||
* this one accidentally used virtual addresses - as such,
|
||||
* its depreciated.
|
||||
*/
|
||||
#define ATAG_INITRD 0x54410005
|
||||
|
||||
/* describes where the compressed ramdisk image lives (physical address) */
|
||||
#define ATAG_INITRD2 0x54420005
|
||||
|
||||
struct tag_initrd {
|
||||
u32 start; /* physical start address */
|
||||
u32 size; /* size of compressed ramdisk image in bytes */
|
||||
};
|
||||
|
||||
/* board serial number. "64 bits should be enough for everybody" */
|
||||
#define ATAG_SERIAL 0x54410006
|
||||
|
||||
struct tag_serialnr {
|
||||
u32 low;
|
||||
u32 high;
|
||||
};
|
||||
|
||||
/* board revision */
|
||||
#define ATAG_REVISION 0x54410007
|
||||
|
||||
struct tag_revision {
|
||||
u32 rev;
|
||||
};
|
||||
|
||||
/* initial values for vesafb-type framebuffers. see struct screen_info
|
||||
* in include/linux/tty.h
|
||||
*/
|
||||
#define ATAG_VIDEOLFB 0x54410008
|
||||
|
||||
struct tag_videolfb {
|
||||
u16 lfb_width;
|
||||
u16 lfb_height;
|
||||
u16 lfb_depth;
|
||||
u16 lfb_linelength;
|
||||
u32 lfb_base;
|
||||
u32 lfb_size;
|
||||
u8 red_size;
|
||||
u8 red_pos;
|
||||
u8 green_size;
|
||||
u8 green_pos;
|
||||
u8 blue_size;
|
||||
u8 blue_pos;
|
||||
u8 rsvd_size;
|
||||
u8 rsvd_pos;
|
||||
};
|
||||
|
||||
/* command line: \0 terminated string */
|
||||
#define ATAG_CMDLINE 0x54410009
|
||||
|
||||
struct tag_cmdline {
|
||||
char cmdline[1]; /* this is the minimum size */
|
||||
};
|
||||
|
||||
/* acorn RiscPC specific information */
|
||||
#define ATAG_ACORN 0x41000101
|
||||
|
||||
struct tag_acorn {
|
||||
u32 memc_control_reg;
|
||||
u32 vram_pages;
|
||||
u8 sounddefault;
|
||||
u8 adfsdrives;
|
||||
};
|
||||
|
||||
/* footbridge memory clock, see arch/arm/mach-footbridge/arch.c */
|
||||
#define ATAG_MEMCLK 0x41000402
|
||||
|
||||
struct tag_memclk {
|
||||
u32 fmemclk;
|
||||
};
|
||||
|
||||
struct tag {
|
||||
struct tag_header hdr;
|
||||
union {
|
||||
struct tag_core core;
|
||||
struct tag_mem32 mem;
|
||||
struct tag_videotext videotext;
|
||||
struct tag_ramdisk ramdisk;
|
||||
struct tag_initrd initrd;
|
||||
struct tag_serialnr serialnr;
|
||||
struct tag_revision revision;
|
||||
struct tag_videolfb videolfb;
|
||||
struct tag_cmdline cmdline;
|
||||
|
||||
/*
|
||||
* Acorn specific
|
||||
*/
|
||||
struct tag_acorn acorn;
|
||||
|
||||
/*
|
||||
* DC21285 specific
|
||||
*/
|
||||
struct tag_memclk memclk;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct tagtable {
|
||||
u32 tag;
|
||||
int (*parse)(const struct tag *);
|
||||
};
|
||||
|
||||
#define __tag __attribute__((unused, __section__(".taglist")))
|
||||
#define __tagtable(tag, fn) \
|
||||
static struct tagtable __tagtable_##fn __tag = { tag, fn }
|
||||
|
||||
#define tag_member_present(tag,member) \
|
||||
((unsigned long)(&((struct tag *)0L)->member + 1) \
|
||||
<= (tag)->hdr.size * 4)
|
||||
|
||||
#define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size))
|
||||
#define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
|
||||
|
||||
#define for_each_tag(t,base) \
|
||||
for (t = base; t->hdr.size; t = tag_next(t))
|
||||
|
||||
/*
|
||||
* Memory map description
|
||||
*/
|
||||
#define NR_BANKS 8
|
||||
|
||||
struct meminfo {
|
||||
int nr_banks;
|
||||
unsigned long end;
|
||||
struct {
|
||||
unsigned long start;
|
||||
unsigned long size;
|
||||
int node;
|
||||
} bank[NR_BANKS];
|
||||
};
|
||||
|
||||
extern struct meminfo meminfo;
|
||||
|
||||
#endif
|
@ -27,7 +27,7 @@ int delay(int time)
|
||||
for(i=0;i<time;i++);
|
||||
return 0;
|
||||
}
|
||||
int set_GPB()
|
||||
int set_GPB(void)
|
||||
{
|
||||
GPBCON = 0x5;
|
||||
GPBDW = 0xffff;
|
||||
|
@ -36,6 +36,6 @@
|
||||
|
||||
int orange_on(int times);
|
||||
int blue_on(int times);
|
||||
int blink_led();
|
||||
int blink_led(void);
|
||||
|
||||
#endif /* __BLINK_LED_H */
|
||||
|
@ -32,17 +32,16 @@ SECTIONS
|
||||
. = ALIGN(4);
|
||||
.text :
|
||||
{
|
||||
src/start.o (.text)
|
||||
src/lowlevel_init.o(.text)
|
||||
src/start_kboot.o (.text .rodata)
|
||||
*(.text .rodata)
|
||||
src/start.o (.text .rodata* .data)
|
||||
src/lowlevel_init.o(.text .rodata* .data)
|
||||
src/start_kboot.o (.text .rodata* .data)
|
||||
src/serial.o (.text .rodata* .data)
|
||||
src/blink_led.o (.text .rodata* .data)
|
||||
* (.rodata* .data)
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
}
|
||||
.everything_else : { *(.text) }
|
||||
|
||||
. = ALIGN(4);
|
||||
.got :
|
||||
@ -50,7 +49,7 @@ SECTIONS
|
||||
*(.got)
|
||||
}
|
||||
|
||||
. = ALIGN(4);
|
||||
. = 0x32000000 ;
|
||||
__bss_start = .;
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
|
@ -11,6 +11,7 @@ int vsprintf(char *buf, const char *fmt, va_list args);
|
||||
int puts(const char *string);
|
||||
void printhex(unsigned char v);
|
||||
void print32(unsigned int u);
|
||||
void hexdump(unsigned char *start, int len);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -89,6 +89,8 @@ static int nand_read_page_ll(unsigned char *buf, unsigned long addr)
|
||||
{
|
||||
unsigned short *ptr16 = (unsigned short *)buf;
|
||||
unsigned int i, page_num;
|
||||
unsigned char ecc[64];
|
||||
unsigned short *p16 = (unsigned short *)ecc;
|
||||
|
||||
nand_clear_RnB();
|
||||
|
||||
@ -104,9 +106,11 @@ static int nand_read_page_ll(unsigned char *buf, unsigned long addr)
|
||||
NFCMD = NAND_CMD_READSTART;
|
||||
nand_wait();
|
||||
|
||||
for (i = 0; i < NAND_PAGE_SIZE/2; i++) {
|
||||
*ptr16 = NFDATA16;
|
||||
ptr16++;
|
||||
for (i = 0; i < NAND_PAGE_SIZE/2; i++)
|
||||
*ptr16++ = NFDATA16;
|
||||
|
||||
for (i = 0; i < 64 / 2; i++) {
|
||||
*p16++ = NFDATA16;
|
||||
}
|
||||
|
||||
return NAND_PAGE_SIZE;
|
||||
@ -129,26 +133,20 @@ int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
|
||||
;
|
||||
|
||||
for (i = start_addr; i < (start_addr + size);) {
|
||||
#ifdef DEBUG
|
||||
serial_putc(2, 'i');
|
||||
if ((i & (NAND_BLOCK_SIZE - 1)) == 0) {
|
||||
if (is_bad_block(i) ||
|
||||
is_bad_block(i + NAND_PAGE_SIZE)) {
|
||||
serial_putc(2, '!');
|
||||
serial_putc(2, '0');
|
||||
serial_putc(2, 'x');
|
||||
print32((unsigned int)i);
|
||||
serial_putc(2, ' ');
|
||||
#endif
|
||||
if (i % NAND_BLOCK_SIZE == 0) {
|
||||
if (is_bad_block(i) ||
|
||||
is_bad_block(i + NAND_PAGE_SIZE)) {
|
||||
#ifdef DEBUG
|
||||
serial_putc(2, '?');
|
||||
#endif
|
||||
|
||||
i += NAND_BLOCK_SIZE;
|
||||
size += NAND_BLOCK_SIZE;
|
||||
if (bad_count++ == 4) {
|
||||
#ifdef DEBUG
|
||||
serial_putc(2, '+');
|
||||
serial_putc(2, '\n');
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
serial_putc(2, '\n');
|
||||
@ -157,18 +155,8 @@ int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
|
||||
}
|
||||
|
||||
j = nand_read_page_ll(buf, i);
|
||||
#ifdef DEBUG
|
||||
serial_putc(2, 'j');
|
||||
serial_putc(2, '0');
|
||||
serial_putc(2, 'x');
|
||||
print32((unsigned int)j);
|
||||
serial_putc(2, ' ');
|
||||
#endif
|
||||
i += j;
|
||||
buf += j;
|
||||
#if DEBUG
|
||||
serial_putc(2, '\n');
|
||||
#endif
|
||||
}
|
||||
|
||||
/* chip Disable */
|
||||
|
@ -109,6 +109,23 @@ void print32(unsigned int u)
|
||||
printhex(u);
|
||||
}
|
||||
|
||||
void hexdump(unsigned char *start, int len)
|
||||
{
|
||||
int n;
|
||||
|
||||
while (len > 0) {
|
||||
print32((int)start);
|
||||
serial_putc(DEBUG_CONSOLE_UART, ':');
|
||||
serial_putc(DEBUG_CONSOLE_UART, ' ');
|
||||
for (n = 0; n < 16; n++) {
|
||||
printhex(*start++);
|
||||
serial_putc(DEBUG_CONSOLE_UART, ' ');
|
||||
}
|
||||
serial_putc(DEBUG_CONSOLE_UART, '\n');
|
||||
len -= 16;
|
||||
}
|
||||
}
|
||||
|
||||
int printk(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
@ -35,7 +35,8 @@ extern void bootloader_second_phase(void);
|
||||
|
||||
void start_kboot(void)
|
||||
{
|
||||
void (*phase2)(void) = bootloader_second_phase + TEXT_BASE;
|
||||
void (*phase2)(void) = (void (*)(void))((int)bootloader_second_phase +
|
||||
TEXT_BASE);
|
||||
|
||||
port_init();
|
||||
serial_init(0x11, UART2);
|
||||
@ -43,18 +44,15 @@ void start_kboot(void)
|
||||
puts("Openmoko KBOOT "stringify2(BUILD_HOST)" "
|
||||
stringify2(BUILD_VERSION)" "
|
||||
stringify2(BUILD_DATE)"\n");
|
||||
|
||||
/*
|
||||
* pull the whole U-Boot image into SDRAM
|
||||
* pull the whole bootloader image into SDRAM
|
||||
*/
|
||||
|
||||
if (nand_read_ll((unsigned char *)TEXT_BASE, 0, 256 * 1024) < 0)
|
||||
if (nand_read_ll((unsigned char *)TEXT_BASE, 0, 24 * 1024) < 0)
|
||||
while(1)
|
||||
blink_led();
|
||||
|
||||
/*
|
||||
* jump to bootloader_second_phase() running from DRAM copy
|
||||
*/
|
||||
|
||||
(phase2)();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user