[PATCH 12/15] add-kernel-init.patch

xiangfu xiangfu at openmoko.org
Wed Aug 13 02:39:22 CEST 2008


i am reading the code.
awesome

Andy Green wrote:
> 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 at openmoko.com>
> ---
>
>  Makefile             |    5 
>  include/image.h      |  572 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  include/serial.h     |    1 
>  include/setup.h      |  269 ++++++++++++++++++++++++
>  src/blink_led.c      |    2 
>  src/blink_led.h      |    2 
>  src/kboot-stage1.lds |   17 +
>  src/kboot.h          |    1 
>  src/nand_read.c      |   40 +--
>  src/serial.c         |   17 +
>  src/start_kboot.c    |   10 -
>  11 files changed, 890 insertions(+), 46 deletions(-)
>  create mode 100644 include/image.h
>  create mode 100644 include/setup.h
>
> diff --git a/Makefile b/Makefile
> index b279e25..1a73ddb 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -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 = 
> diff --git a/include/image.h b/include/image.h
> new file mode 100644
> index 0000000..2e3c6ef
> --- /dev/null
> +++ b/include/image.h
> @@ -0,0 +1,572 @@
> +/*
> + * (C) Copyright 2008 Semihalf
> + *
> + * (C) Copyright 2000-2005
> + * Wolfgang Denk, DENX Software Engineering, wd at 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__ */
> diff --git a/include/serial.h b/include/serial.h
> index 12e2ae9..732fe67 100644
> --- a/include/serial.h
> +++ b/include/serial.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
> diff --git a/include/setup.h b/include/setup.h
> new file mode 100644
> index 0000000..89df4dc
> --- /dev/null
> +++ b/include/setup.h
> @@ -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
> diff --git a/src/blink_led.c b/src/blink_led.c
> index fa4482e..e1e7a94 100644
> --- a/src/blink_led.c
> +++ b/src/blink_led.c
> @@ -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;
> diff --git a/src/blink_led.h b/src/blink_led.h
> index c0b05b5..8485404 100644
> --- a/src/blink_led.h
> +++ b/src/blink_led.h
> @@ -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 */
> diff --git a/src/kboot-stage1.lds b/src/kboot-stage1.lds
> index 4b93b52..7987801 100644
> --- a/src/kboot-stage1.lds
> +++ b/src/kboot-stage1.lds
> @@ -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) : 
>      { 
> diff --git a/src/kboot.h b/src/kboot.h
> index 7143aae..1c70dda 100644
> --- a/src/kboot.h
> +++ b/src/kboot.h
> @@ -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
>  
> diff --git a/src/nand_read.c b/src/nand_read.c
> index 8deadb7..16310bb 100644
> --- a/src/nand_read.c
> +++ b/src/nand_read.c
> @@ -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');
> -		serial_putc(2, '0');
> -		serial_putc(2, 'x');
> -		print32((unsigned int)i);
> -		serial_putc(2, ' ');
> -#endif
> -		if (i % NAND_BLOCK_SIZE == 0) {
> +		if ((i & (NAND_BLOCK_SIZE - 1)) == 0) {
>  			if (is_bad_block(i) ||
>  					is_bad_block(i + NAND_PAGE_SIZE)) {
> -#ifdef DEBUG
> -				serial_putc(2, '?');
> -#endif
> +				serial_putc(2, '!');
> +				serial_putc(2, '0');
> +				serial_putc(2, 'x');
> +				print32((unsigned int)i);
> +				serial_putc(2, ' ');
> +
>  				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 */
> diff --git a/src/serial.c b/src/serial.c
> index 8c8c2a5..5fb8b04 100644
> --- a/src/serial.c
> +++ b/src/serial.c
> @@ -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;
> diff --git a/src/start_kboot.c b/src/start_kboot.c
> index 10badfa..2e2c605 100644
> --- a/src/start_kboot.c
> +++ b/src/start_kboot.c
> @@ -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)();
>  }
>
>
>   





More information about the openmoko-kernel mailing list