[[RFC] 01/14] Add a tool to activate barebox as a boot loader on x86 architectures

Sascha Hauer s.hauer at pengutronix.de
Fri Dec 11 07:25:54 EST 2009


On Thu, Dec 10, 2009 at 06:25:28PM +0100, Juergen Beisert wrote:
> To use barebox as a BIOS based bootloader for x86 architectures, the binary
> must be patched to get it bootstrapped at runtime. The 'setupmbr' tool installs
> the barebox-binary to the given device node or image file and patch it in
> accordance to the needed sector information at runtime.
> 
> Signed-off by: Juergen Beisert <jbe at pengutronix.de>
> 
> ---
>  Doxyfile                    |    3 
>  scripts/Makefile            |    4 
>  scripts/setupmbr/Makefile   |    4 
>  scripts/setupmbr/arch.h     |   55 +++
>  scripts/setupmbr/setupmbr.c |  705 ++++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 769 insertions(+), 2 deletions(-)
> 
> Index: u-boot-2.0.0-rc10/scripts/Makefile
> ===================================================================
> --- u-boot-2.0.0-rc10.orig/scripts/Makefile
> +++ u-boot-2.0.0-rc10/scripts/Makefile
> @@ -24,5 +24,7 @@ hostprogs-y += unifdef
>  #subdir-$(CONFIG_MODVERSIONS) += genksyms
>  subdir-y                     += mod
>  
> +subdir-$(CONFIG_X86)             += setupmbr
> +
>  # Let clean descend into subdirs
> -subdir-	+= basic kconfig
> +subdir-	+= basic kconfig setupmbr
> Index: u-boot-2.0.0-rc10/scripts/setupmbr/Makefile
> ===================================================================
> --- /dev/null
> +++ u-boot-2.0.0-rc10/scripts/setupmbr/Makefile
> @@ -0,0 +1,4 @@
> +HOST_EXTRACFLAGS=-I$(srctree)
> +
> +hostprogs-y  := setupmbr
> +always       := $(hostprogs-y)
> Index: u-boot-2.0.0-rc10/scripts/setupmbr/arch.h
> ===================================================================
> --- /dev/null
> +++ u-boot-2.0.0-rc10/scripts/setupmbr/arch.h
> @@ -0,0 +1,55 @@
> +
> +/* we need the one from the host */
> +#include <endian.h>
> +#include <stdint.h>
> +
> +/* Byte-orders.  */
> +#define swap16(x)	\
> +({ \
> +   uint16_t _x = (x); \
> +   (uint16_t) ((_x << 8) | (_x >> 8)); \
> +})
> +
> +#define swap32(x)	\
> +({ \
> +   uint32_t _x = (x); \
> +   (uint32_t) ((_x << 24) \
> +                    | ((_x & (uint32_t) 0xFF00UL) << 8) \
> +                    | ((_x & (uint32_t) 0xFF0000UL) >> 8) \
> +                    | (_x >> 24)); \
> +})
> +
> +#define swap64(x)	\
> +({ \
> +   uint64_t _x = (x); \
> +   (uint64_t) ((_x << 56) \
> +                    | ((_x & (uint64_t) 0xFF00ULL) << 40) \
> +                    | ((_x & (uint64_t) 0xFF0000ULL) << 24) \
> +                    | ((_x & (uint64_t) 0xFF000000ULL) << 8) \
> +                    | ((_x & (uint64_t) 0xFF00000000ULL) >> 8) \
> +                    | ((_x & (uint64_t) 0xFF0000000000ULL) >> 24) \
> +                    | ((_x & (uint64_t) 0xFF000000000000ULL) >> 40) \
> +                    | (_x >> 56)); \
> +})
> +
> +#if __BYTE_ORDER == __BIG_ENDIAN
> +
> +/* Our target is a ia32 machine, always little endian */
> +
> +# define host2target_16(x)	swap16(x)
> +# define host2target_32(x)	swap32(x)
> +# define host2target_64(x)	swap64(x)
> +# define target2host_16(x)	swap16(x)
> +# define target2host_32(x)	swap32(x)
> +# define target2host_64(x)	swap64(x)
> +
> +#else
> +
> +# define host2target_16(x)	(x)
> +# define host2target_32(x)	(x)
> +# define host2target_64(x)	(x)
> +# define target2host_16(x)	(x)
> +# define target2host_32(x)	(x)
> +# define target2host_64(x)	(x)

endian.h defines htole[16|32|64] which should be what you need here.


> +
> +#endif
> Index: u-boot-2.0.0-rc10/scripts/setupmbr/setupmbr.c
> ===================================================================
> --- /dev/null
> +++ u-boot-2.0.0-rc10/scripts/setupmbr/setupmbr.c
> @@ -0,0 +1,705 @@
> +/*
> + * Copyright (C) 2009 Juergen Beisert, Pengutronix
> + *
> + * 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
> + *
> + */
> +
> +/**
> + * @file
> + * @brief Write the barebox binary to the MBR and the following disk sectors
> + *
> + * Also patch dedicated locations in the image to make it work at runtime
> + *
> + * Current restrictions are:
> + * - only installs into MBR and the sectors after it
> + * - tested only with QEMU
> + * - and maybe some others
> + */
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <stdint.h>
> +#include <sys/mman.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <string.h>
> +#include <assert.h>
> +
> +/* include the info from this barebox release */
> +#include "include/linux/utsrelease.h"
> +#include "arch/x86/include/asm/u-boot.lds.h"
> +
> +/** define to disable integrity tests and debug messages */
> +#define NDEBUG
> +
> +/* some infos about our target architecture */
> +#include "arch.h"
> +
> +/**
> + * "Disk Address Packet Structure" to be used when calling int13,
> + * function 0x42
> + *
> + * @note All entries are in target endianess
> + */
> +struct DAPS
> +{
> +	uint8_t size;		/**< size of this data set, 0 marks it as invalid */
> +	uint8_t res1;		/**< always 0 */
> +	int8_t count;		/**< number of sectors 0...127 to handle */
> +	uint8_t res2;		/**< always 0 */
> +	uint16_t offset;	/**< store address: offset */
> +	uint16_t segment;	/**< store address: segment */
> +	uint64_t lba;		/**< start sector number in LBA */
> +} __attribute__ ((packed));
> +
> +/**
> + * Description of one partition table entry (D*S type)
> + *
> + * @note All entries are in target endianess
> + */
> +struct partition_entry {
> +	uint8_t boot_indicator;
> +	uint8_t chs_begin[3];
> +	uint8_t type;
> +	uint8_t chs_end[3];
> +	uint32_t partition_start;	/* LE */
> +	uint32_t partition_size;	/* LE */
> +} __attribute__ ((packed));
> +
> +#ifndef NDEBUG

#ifdef DEBUG instead?

> +static void debugout(const struct DAPS *entry, int supress_entry)
> +{
> +	if (supress_entry)
> +		printf("DAPS entry: ");
> +	else
> +		printf("DAPS entry % 3u: ", ((unsigned)entry & ( SECTOR_SIZE - 1)) / sizeof(struct DAPS));
> +
> +	printf("Size: % 2u, Count: % 3d, Offset: 0x%04hX, Segment: 0x%04hX, LBA: %llu\n",
> +		entry->size, entry->count,
> +		target2host_16(entry->offset), target2host_16(entry->segment),
> +		target2host_64(entry->lba));
> +}
> +#else
> +# define debugout(x,y) (__ASSERT_VOID_CAST(0))
> +#endif
> +
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |




More information about the u-boot-v2 mailing list