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@xxxxxxxxxxxxxx> > > --- > 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 | _______________________________________________ u-boot-v2 mailing list u-boot-v2@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/u-boot-v2