Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 4 Apr 2011 02:48:56 +0900
From:      rozhuk.im@gmail.com
To:        <freebsd-arm@freebsd.org>, <freebsd-geom@freebsd.org>
Subject:   RE: merge geom redboot and map
Message-ID:  <4d98b30d.581ce30a.3a77.ffffc4d6@mx.google.com>
In-Reply-To: <20110330232735.3768cbb6.ray@ddteam.net>
References:  <4d9351fb.1d32dc0a.2d95.070c@mx.google.com>	<56D961DF-74C4-4E1B-B7F5-60E0E939DE8E@bsdimp.com>	<4d938233.1192e60a.2761.1205@mx.google.com> <20110330232735.3768cbb6.ray@ddteam.net>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.

------=_NextPart_000_0076_01CBF272.D99FC070
Content-Type: text/plain;
	charset="windows-1251"
Content-Transfer-Encoding: quoted-printable

Hi all!


I need Your help with testing and adding code to FreeBSD sources.

Not tested:
- redboot/FIS
- map search by key


Build options:
options	GEOM_MAP			#=20
options	GEOM_MAP_NO_REDBOOT	# turn off redboot/fis support



Static mappings in hints:
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D
# Area 0: 30000000 to 3002FFFF (0 - 196607, size: 196607) : =
"Bootloader":
u-boot
# Area 1: 30030000 to 3003FFFF (196608 - 262143, size: 65535) : =
"Factory":
u-boot env
# Area 2: 30040000 to 3023FFFF (262144 - 2359295, size: 2097151) : =
"Kernel"
# Area 3: 30240000 to 307FFFFF (2359296 - 8388607, size: 6029311) : =
"RootFS"

hint.map.0.at =3D	"flash/spi0"
hint.map.0.start =3D	0x00000000
hint.map.0.end =3D	0x00030000
hint.map.0.name =3D	"bootldr"
hint.map.0.readonly =3D1

hint.map.1.at =3D	"flash/spi0"
hint.map.1.start =3D	0x00030000
hint.map.1.end =3D	0x00040000
hint.map.1.name =3D	"bootldr_env"
hint.map.1.readonly =3D1

hint.map.2.at =3D	"flash/spi0"
hint.map.2.start =3D	0x00040000
hint.map.2.end =3D	0x00240000
hint.map.2.name =3D	"kernel"
hint.map.2.readonly =3D0

hint.map.3.at =3D	"flash/spi0"
hint.map.3.start =3D	0x00240000
hint.map.3.end =3D	0x00800000
hint.map.3.name =3D	"rootfs"
hint.map.3.readonly =3D0
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D



Boot log:
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D
...
GEOM_MAP: /dev/flash/spi0: 0x00000000-0x00030000, offset=3D0x0, R/O,
size=3D196608 bytes at: "/dev/map/spi0bootldr"
GEOM_MAP: /dev/flash/spi0: 0x00030000-0x00040000, offset=3D0x0, R/O,
size=3D65536 bytes at: "/dev/map/spi0bootldr_env"
GEOM_MAP: /dev/flash/spi0: 0x00040000-0x00240000, offset=3D0x0, R/W,
size=3D2097152 bytes at: "/dev/map/spi0kernel"
GEOM_MAP: /dev/flash/spi0: 0x00240000-0x00800000, offset=3D0x0, R/W,
size=3D6029312 bytes at: "/dev/map/spi0rootfs"
GEOM_MAP: /dev/flash/spi0: FIS/RedBoot not exist, incompatible =
blksize=3D0
GEOM_MAP: /dev/flash/spi0: mediasize=3D8388608, secsize=3D65536, =
blksize=3D0
...
GEOM_MAP: /dev/da0: FIS/RedBoot not exist, incompatible blksize=3D0
GEOM_MAP: /dev/da0p1: FIS/RedBoot not exist, incompatible blksize=3D0
GEOM_MAP: /dev/gpt/Documental: FIS/RedBoot not exist, incompatible =
blksize=3D0
GEOM_MAP: /dev/gptid/ca70d533-5759-11e0-b900-001a4d559a42: FIS/RedBoot =
not
exist, incompatible blksize=3D0
Mounting local file systems:GEOM_MAP: /dev/md0: FIS/RedBoot not exist,
incompatible blksize=3D0
GEOM_MAP: /dev/ufsid/4d98a59e587419bf: FIS/RedBoot not exist, =
incompatible
blksize=3D0
GEOM_MAP: /dev/md0: FIS/RedBoot not exist, incompatible blksize=3D0
GEOM_MAP: /dev/ufsid/4d98a967c292e50d: FIS/RedBoot not exist, =
incompatible
blksize=3D0
GEOM_MAP: /dev/md1: FIS/RedBoot not exist, incompatible blksize=3D0
GEOM_MAP: /dev/md1: FIS/RedBoot not exist, incompatible blksize=3D0
GEOM_MAP: /dev/ufsid/4d98a968674909d4: FIS/RedBoot not exist, =
incompatible
blksize=3D0
...
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D



Files:
 - geom_map.c - source of geom node
 - options_add_geom_map.txt - patch to add build options
 - subr_hints.txt - kernel api to read 64bit values from hints
http://www.freebsd.org/cgi/query-pr.cgi?pr=3D156130



=A0
--
Rozhuk Ivan
=A0=20


> -----Original Message-----
> From: Aleksandr Rybalko [mailto:ray@ddteam.net]
> Sent: Thursday, March 31, 2011 5:28 AM
> To: Rozhuk.IM@gmail.com
> Cc: rozhuk.im@gmail.com; 'Warner Losh'; freebsd-arm@freebsd.org;
> freebsd-geom@freebsd.org
> Subject: Re: merge geom redboot and map
>=20
> Hi all,
>=20
> On Thu, 31 Mar 2011 04:19:11 +0900
> rozhuk.im@gmail.com wrote:
>=20
> >
> > > > I need your opinions, suggestions and help with testing and
> > > > including
> > > code
> > > > to main stream source tree.
> > >
> > > I think this likely is a good refactoring.
> > >
> > > > PS: I can test only "map" part on my Agestar LB2.
> > >
> > > But please make sure FIS still works.
> >
> > I hope peoples with redboot hardware help with testing.
> >
> >
> > Another question is path to mapped block (partition)?
> >
> > Now
> > - redboot: /dev/redboot/%name
> > - map: /dev/map/%name
> >
> > Variants:
> > 1. stay as is
> > 2. /dev/flash/%name
> > 3. ?
>=20
> 3. /dev/flash/spi0kernel, /dev/flash/spi0rootfs, ...
>=20
> IMO, /dev/map/ more generic :)
>=20
> >
> > _______________________________________________
> > freebsd-arm@freebsd.org mailing list
> > http://lists.freebsd.org/mailman/listinfo/freebsd-arm
> > To unsubscribe, send any mail to "freebsd-arm-
> unsubscribe@freebsd.org"
>=20
> P.S.
>=20
> I think GEOM_FLASH_NO_MAP not needed,
> because this modules differ only on configuration source,
> REDBOOT partition map and hints, so maybe only GEOM_FLASH_NO_REDBOOT =
to
> avoid unwanted read.
>=20
> WBW
> --
> Aleksandr Rybalko <ray@ddteam.net>

------=_NextPart_000_0076_01CBF272.D99FC070
Content-Type: text/plain;
	name="subr_hints.txt"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="subr_hints.txt"

--- /usr/src/sys/kern/subr_hints_orig.c 2009-08-03 17:13:06.000000000 =
+0900
+++ /usr/src/sys/kern/subr_hints.c      2011-04-03 18:10:57.000000000 =
+0900
@@ -273,6 +273,30 @@
        return 0;
 }
=20
+
+int
+resource_quad_t_value(const char *name, int unit, const char *resname, =
quad_t *result)
+{
+       int error;
+       const char *str;
+       char *op;
+       quad_t val;
+       int line;
+
+       line =3D 0;
+       error =3D resource_find(&line, NULL, name, &unit, resname, NULL,
+           NULL, NULL, NULL, NULL, NULL, &str);
+       if (error)
+               return error;
+       if (*str =3D=3D '\0')=20
+               return EFTYPE;
+       val =3D strtoq(str, &op, 0);
+       if (*op !=3D '\0')=20
+               return EFTYPE;
+       *result =3D val;
+       return 0;
+}
+
 int
 resource_string_value(const char *name, int unit, const char *resname,
     const char **result)


--- /usr/src/sys/sys/bus.h_orig 2011-02-09 06:08:00.000000000 +0800
+++ /usr/src/sys/sys/bus.h      2011-04-03 18:13:07.000000000 +0900
@@ -470,6 +470,8 @@
                           int *result);
 int    resource_long_value(const char *name, int unit, const char =
*resname,
                            long *result);
+int    resource_quad_t_value(const char *name, int unit, const char =
*resname,
+                               quad_t *result);
 int    resource_string_value(const char *name, int unit, const char =
*resname,
                              const char **result);
 int    resource_disabled(const char *name, int unit);


------=_NextPart_000_0076_01CBF272.D99FC070
Content-Type: text/plain;
	name="geom_map.c"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="geom_map.c"

/*-=0A=
 * Copyright (c) 2009 Aleksandr Rybalko AKA Alex RAY, DDTeam.net=0A=
 * based on geom_redboot.c=0A=
 * Copyright (c) 2009 Sam Leffler, Errno Consulting=0A=
 * All rights reserved.=0A=
 *=0A=
 * Redistribution and use in source and binary forms, with or without=0A=
 * modification, are permitted provided that the following conditions=0A=
 * are met:=0A=
 * 1. Redistributions of source code must retain the above copyright=0A=
 *    notice, this list of conditions and the following disclaimer,=0A=
 *    without modification.=0A=
 * 2. Redistributions in binary form must reproduce at minimum a =
disclaimer=0A=
 *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and =
any=0A=
 *    redistribution must be conditioned upon including a substantially=0A=
 *    similar Disclaimer requirement for further binary redistribution.=0A=
 *=0A=
 * NO WARRANTY=0A=
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS=0A=
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT=0A=
 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY=0A=
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL=0A=
 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, =
EXEMPLARY,=0A=
 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT =
OF=0A=
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR =
BUSINESS=0A=
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER=0A=
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR =
OTHERWISE)=0A=
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF=0A=
 * THE POSSIBILITY OF SUCH DAMAGES.=0A=
 */=0A=
=0A=
=0A=
#include <sys/cdefs.h>=0A=
__FBSDID("$FreeBSD$");=0A=
=0A=
#include <sys/param.h>=0A=
#include <sys/bus.h>=0A=
#include <sys/errno.h>=0A=
#include <sys/endian.h>=0A=
#include <sys/systm.h>=0A=
#include <sys/kernel.h>=0A=
#include <sys/fcntl.h>=0A=
#include <sys/malloc.h>=0A=
#include <sys/bio.h>=0A=
#include <sys/lock.h>=0A=
#include <sys/mutex.h>=0A=
=0A=
#include <sys/sbuf.h>=0A=
#include <geom/geom.h>=0A=
#include <geom/geom_slice.h>=0A=
#include "opt_geom.h"=0A=
=0A=
=0A=
#define MAP_CLASS_NAME		"MAP"=0A=
#define MAP_MAXSLICE			64=0A=
#define MAP_SEARCH_KEY_LEN_MAX	255=0A=
#define MAP_SEARCH_STEP_DEF		0x10000U=0A=
=0A=
=0A=
struct g_map_softc {=0A=
	g_access_t	*parent_access;=0A=
	off_t		entry[MAP_MAXSLICE];		/* offset in image for entry point */=0A=
	off_t		dsize[MAP_MAXSLICE];		/* data size in bytes */=0A=
	u_int		readonly[MAP_MAXSLICE];=0A=
};=0A=
=0A=
=0A=
=0A=
#if !defined(GEOM_MAP_NO_REDBOOT)=0A=
=0A=
struct fis_image_desc {=0A=
	uint8_t	name   [16];	/* null-terminated name */=0A=
	uint32_t	offset;	/* offset in flash */=0A=
	uint32_t	addr;		/* address in memory */=0A=
	uint32_t	size;		/* image size in bytes */=0A=
	uint32_t	entry;		/* offset in image for entry point */=0A=
	uint32_t	dsize;		/* data size in bytes */=0A=
	uint8_t	pad[256-(16+7*sizeof(uint32_t)+sizeof(void*))];=0A=
	struct fis_image_desc *next;	/* linked list (in memory) */=0A=
	uint32_t	dsum;		/* descriptor checksum */=0A=
	uint32_t	fsum;		/* checksum over image data */=0A=
};=0A=
=0A=
#define FISDIR_NAME			"FIS directory"=0A=
#define REDBCFG_NAME			"RedBoot config"=0A=
#define REDBOOT_NAME			"RedBoot"=0A=
=0A=
#endif /* !defined(GEOM_MAP_NO_REDBOOT) */=0A=
=0A=
=0A=
=0A=
=0A=
static int=0A=
g_map_ioctl(struct g_provider *pp, u_long cmd, void *data, int fflag, =
struct thread *td)=0A=
{=0A=
	return (ENOIOCTL);=0A=
}=0A=
=0A=
static int=0A=
g_map_access(struct g_provider *pp, int dread, int dwrite, int dexcl)=0A=
{=0A=
	struct g_geom *gp =3D pp->geom;=0A=
	struct g_slicer *gsp =3D gp->softc;=0A=
	struct g_map_softc *sc =3D gsp->softc;=0A=
=0A=
	if (dwrite > 0 && sc->readonly[pp->index])=0A=
		return (EPERM);=0A=
	return (sc->parent_access(pp, dread, dwrite, dexcl)); =0A=
}=0A=
=0A=
static int=0A=
g_map_start(struct bio *bp)=0A=
{=0A=
	struct g_provider *pp;=0A=
	struct g_geom *gp;=0A=
	struct g_map_softc *sc;=0A=
	struct g_slicer *gsp;=0A=
	int idx;=0A=
=0A=
	pp =3D bp->bio_to;=0A=
	idx =3D pp->index;=0A=
	gp =3D pp->geom;=0A=
	gsp =3D gp->softc;=0A=
	sc =3D gsp->softc;=0A=
	if (bp->bio_cmd =3D=3D BIO_GETATTR) {=0A=
		if (g_handleattr_off_t(bp, MAP_CLASS_NAME "::entry", sc->entry[idx]))=0A=
			return (1);=0A=
		if (g_handleattr_off_t(bp, MAP_CLASS_NAME "::dsize", sc->dsize[idx]))=0A=
			return (1);=0A=
	}=0A=
	return (0);=0A=
}=0A=
=0A=
static void=0A=
g_map_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp,=0A=
	       struct g_consumer *cp __unused, struct g_provider *pp)=0A=
{=0A=
	struct g_map_softc *sc;=0A=
	struct g_slicer *gsp;=0A=
=0A=
	gsp =3D gp->softc;=0A=
	sc =3D gsp->softc;=0A=
	g_slice_dumpconf(sb, indent, gp, cp, pp);=0A=
	if (pp !=3D NULL) {=0A=
		if (indent =3D=3D NULL) {=0A=
			sbuf_printf(sb, " entry %jd", sc->entry[pp->index]);=0A=
			sbuf_printf(sb, " dsize %jd", sc->dsize[pp->index]);=0A=
			sbuf_printf(sb, " readonly %u", sc->readonly[pp->index]);=0A=
		} else {=0A=
			sbuf_printf(sb, "%s<entry>%jd</entry>\n", indent, =
sc->entry[pp->index]);=0A=
			sbuf_printf(sb, "%s<dsize>%jd</dsize>\n", indent, =
sc->dsize[pp->index]);=0A=
			sbuf_printf(sb, "%s<readonly>%u</readonly>\n", indent, =
sc->readonly[pp->index]);=0A=
		}=0A=
	}=0A=
}=0A=
=0A=
=0A=
=0A=
#include <sys/ctype.h>=0A=
=0A=
=0A=
=0A=
#if !defined(GEOM_MAP_NO_REDBOOT)=0A=
=0A=
static void=0A=
g_map_print_redboot(int i, struct fis_image_desc *fd)=0A=
{=0A=
	printf("[%2d] \"%-15.15s\" %08x:%08x", i, fd->name, fd->offset, =
fd->size);=0A=
	printf(" addr %08x entry %08x\n", fd->addr, fd->entry);=0A=
	printf("     dsize 0x%x dsum 0x%x fsum 0x%x\n", fd->dsize, fd->dsum, =
fd->fsum);=0A=
}=0A=
=0A=
=0A=
static int=0A=
nameok(const char name[16])=0A=
{=0A=
	int i;=0A=
=0A=
	/* descriptor names are null-terminated printable ascii */=0A=
	for (i =3D 0; i < 15; i++)=0A=
		if (!isprint(name[i]))=0A=
			break;=0A=
	return (name[i] =3D=3D '\0');=0A=
}=0A=
=0A=
=0A=
static struct fis_image_desc *=0A=
parse_fis_directory(u_char *buf, size_t bufsize, off_t offset, uint32_t =
offmask)=0A=
{=0A=
#define	match(a,b)	(bcmp(a, b, sizeof(b)-1) =3D=3D 0)=0A=
	struct fis_image_desc *fd, *efd;=0A=
	struct fis_image_desc *fisdir, *redbcfg;=0A=
	struct fis_image_desc *head, **tail;=0A=
	int i;=0A=
=0A=
	fd =3D (struct fis_image_desc *)buf;=0A=
	efd =3D fd + (bufsize / sizeof(struct fis_image_desc));=0A=
#if 0=0A=
	/*=0A=
	 * Find the start of the FIS table.=0A=
	 */=0A=
	while (fd < efd && fd->name[0] !=3D 0xff)=0A=
		fd++;=0A=
	if (fd =3D=3D efd)=0A=
		return (NULL);=0A=
	if (bootverbose)=0A=
		printf("RedBoot FIS table starts at 0x%jx\n",=0A=
		    offset + fd - (struct fis_image_desc *) buf);=0A=
#endif=0A=
	/*=0A=
	 * Scan forward collecting entries in a list.=0A=
	 */=0A=
	fisdir =3D redbcfg =3D NULL;=0A=
	*(tail =3D &head) =3D NULL;=0A=
	for (i =3D 0; fd < efd; i++, fd++) {=0A=
		if (fd->name[0] =3D=3D 0xff)=0A=
			continue;=0A=
		if (match(fd->name, FISDIR_NAME))=0A=
			fisdir =3D fd;=0A=
		else if (match(fd->name, REDBCFG_NAME))=0A=
			redbcfg =3D fd;=0A=
		if (nameok(fd->name)) {=0A=
			/*=0A=
			 * NB: flash address includes platform mapping;=0A=
			 *     strip it so we have only a flash offset.=0A=
			 */=0A=
			fd->offset &=3D offmask;=0A=
			if (bootverbose)=0A=
				g_map_print_redboot(i, fd);=0A=
			*tail =3D fd;=0A=
			*(tail =3D &fd->next) =3D NULL;=0A=
		}=0A=
	}=0A=
	if (fisdir =3D=3D NULL) {=0A=
		if (bootverbose)=0A=
			printf("No RedBoot FIS table located at %ju\n", offset);=0A=
		return (NULL);=0A=
	}=0A=
	if (redbcfg !=3D NULL &&=0A=
	    fisdir->offset + fisdir->size =3D=3D redbcfg->offset) {=0A=
		/*=0A=
		 * Merged FIS/RedBoot config directory.=0A=
		 */=0A=
		if (bootverbose)=0A=
			printf("FIS/RedBoot merged at 0x%jx (not yet)\n",=0A=
			    offset + fisdir->offset);=0A=
		/* XXX */=0A=
	}=0A=
	return head;=0A=
#undef match=0A=
}=0A=
=0A=
=0A=
/* load maps from hints */=0A=
static u_int=0A=
g_map_load_fis(struct g_consumer *cp, u_int idx)=0A=
{=0A=
	struct g_geom *gp;=0A=
	struct g_provider *pp;=0A=
	struct g_slicer *gsp;=0A=
	struct g_map_softc *sc;=0A=
	struct fis_image_desc *fd, *head;=0A=
	u_char *buf;=0A=
	int error;=0A=
	u_int sectorsize, blksize;	/* NB: flash block size stored as stripesize =
*/=0A=
	uint32_t offmask;=0A=
	off_t offset;=0A=
=0A=
=0A=
	gp =3D cp->geom;=0A=
	pp =3D cp->provider;=0A=
	gsp =3D gp->softc;=0A=
	sc =3D gsp->softc;=0A=
=0A=
	sectorsize =3D cp->provider->sectorsize;=0A=
	if (sectorsize < sizeof(struct fis_image_desc) ||=0A=
	    (sectorsize % sizeof(struct fis_image_desc))) {=0A=
		if (bootverbose)=0A=
			printf("GEOM_MAP: /dev/%s: FIS/RedBoot not exist, incompatible =
sectorsize=3D%u\n", pp->name, sectorsize);=0A=
		return (0);=0A=
	}=0A=
=0A=
	blksize =3D cp->provider->stripesize;=0A=
	if (blksize =3D=3D 0) {=0A=
		if (bootverbose)=0A=
			printf("GEOM_MAP: /dev/%s: FIS/RedBoot not exist, incompatible =
blksize=3D%u\n", pp->name, blksize);=0A=
		return (0);=0A=
	}=0A=
=0A=
	if (powerof2(cp->provider->mediasize))=0A=
		offmask =3D cp->provider->mediasize-1;=0A=
	else=0A=
		offmask =3D 0xffffffff;	/* XXX */=0A=
	offset =3D (cp->provider->mediasize - blksize);=0A=
	g_topology_unlock();=0A=
again:=0A=
	head =3D NULL;=0A=
	buf =3D g_read_data(cp, offset, blksize, NULL);=0A=
	if (buf !=3D NULL)=0A=
		head =3D parse_fis_directory(buf, blksize, offset, offmask);=0A=
	if (head =3D=3D NULL && offset !=3D 0) {=0A=
		if (bootverbose)=0A=
			printf("GEOM_MAP: /dev/%s: FIS/RedBoot table not found in last block, =
try firast block\n", pp->name);=0A=
		if (buf !=3D NULL)=0A=
			g_free(buf);=0A=
		offset =3D 0; /* check the front */=0A=
		goto again;=0A=
	}=0A=
	g_topology_lock();=0A=
	if (head =3D=3D NULL) {=0A=
		if (bootverbose)=0A=
			printf("GEOM_MAP: /dev/%s: FIS/RedBoot not found on device\n", =
pp->name);=0A=
		if (buf !=3D NULL)=0A=
			g_free(buf);=0A=
		return (0);=0A=
	}=0A=
=0A=
	/* Craft a slice for each entry. */=0A=
	for (fd =3D head; fd !=3D NULL; fd =3D fd->next) {=0A=
		if (fd->name[0] =3D=3D '\0')=0A=
			continue;=0A=
		error =3D g_slice_config(gp, idx, G_SLICE_CONFIG_SET, fd->offset, =
fd->size, sectorsize, "redboot/%s", fd->name);=0A=
		if (error) {=0A=
			printf("GEOM_MAP: /dev/%s: g_slice_config returns %d for \"%s\"\n", =
pp->name, error, fd->name);=0A=
		}else{=0A=
			sc->entry[idx] =3D fd->entry;=0A=
			sc->dsize[idx] =3D fd->dsize;=0A=
			/* disallow writing hard-to-recover entries */=0A=
			sc->readonly[idx] =3D (strcmp(fd->name, FISDIR_NAME) =3D=3D 0) || =
(strcmp(fd->name, REDBOOT_NAME) =3D=3D 0);=0A=
			idx ++;=0A=
=0A=
			printf("GEOM_MAP: /dev/%s: 0x%08x-0x%08x, offset=3D0x%x, %s, =
size=3D%ul bytes at: \"/dev/redboot/%s\"\n",=0A=
				pp->name, fd->addr, (fd->addr + fd->size), fd->entry, =
(sc->readonly[idx]? "R/O":"R/W"), fd->size, fd->name);=0A=
		}=0A=
	}=0A=
	g_free(buf);=0A=
=0A=
	return(idx);=0A=
}=0A=
=0A=
#endif /* !defined(GEOM_MAP_NO_REDBOOT) */=0A=
=0A=
=0A=
=0A=
/* search given key on some geom */=0A=
static off_t=0A=
g_map_search_key(struct g_consumer *cp, u_int sectorsize, off_t from, =
off_t step, const char *key, u_int key_len)=0A=
{=0A=
	struct g_provider *pp;=0A=
	off_t ret =3D 0, i, mediasize, read_len;=0A=
	u_int c;=0A=
	char key_mask[MAP_SEARCH_KEY_LEN_MAX];=0A=
	u_char *buf;=0A=
=0A=
=0A=
	pp =3D cp->provider;=0A=
	key_len =3D min(MAP_SEARCH_KEY_LEN_MAX, key_len);=0A=
	read_len =3D roundup(key_len, sectorsize);=0A=
	mediasize =3D cp->provider->mediasize;=0A=
=0A=
	if (bootverbose)=0A=
		printf("GEOM_MAP: /dev/%s: searchkey=3D\"%s\", from=3D0x%jx, =
step=3D0x%jx...", pp->name, key, from, step);=0A=
=0A=
	g_topology_unlock();=0A=
	for (i =3D from; i < mediasize && ret =3D=3D 0; i +=3D step) {=0A=
		buf =3D g_read_data(cp, rounddown(i, sectorsize), read_len, NULL);=0A=
		/* read ok? */=0A=
		if (buf =3D=3D NULL)=0A=
			break;=0A=
=0A=
		/* Wildcard, replace '.' with byte from data */=0A=
		bcopy(key, key_mask, key_len);=0A=
		for (c =3D 0; c < key_len; c++)=0A=
			if (key_mask[c] =3D=3D '.')=0A=
				key_mask[c] =3D ((char *)(buf + (i % sectorsize)))[c];=0A=
=0A=
		if (bcmp( (buf + (i % sectorsize)), key_mask, key_len) =3D=3D 0)=0A=
			ret =3D i;=0A=
		g_free(buf);=0A=
	}=0A=
	g_topology_lock();=0A=
	=0A=
	if (bootverbose) {=0A=
		if (ret)=0A=
			printf("found at 0x%jx\n", ret);=0A=
		else=0A=
			printf("NOT found!\n");=0A=
	}=0A=
=0A=
	return(ret);=0A=
}=0A=
=0A=
=0A=
/* load maps from hints */=0A=
static u_int=0A=
g_map_load_hints(struct g_consumer *cp, u_int idx)=0A=
{=0A=
	struct g_geom *gp;=0A=
	struct g_provider *pp;=0A=
	struct g_slicer *gsp;=0A=
	struct g_map_softc *sc;=0A=
	const char *map_name, *tmpstr, *search_key;=0A=
	off_t map_start, map_end, map_size, map_offset, search_start, =
search_step;=0A=
	u_int i, sectorsize, map_readonly, map_start_searched;=0A=
	int ret;=0A=
=0A=
	gp =3D cp->geom;=0A=
	pp =3D cp->provider;=0A=
	gsp =3D gp->softc;=0A=
	sc =3D gsp->softc;=0A=
=0A=
	sectorsize =3D cp->provider->sectorsize;=0A=
=0A=
	for (i =3D 0; i < MAP_MAXSLICE; i++) {=0A=
		map_start =3D map_end =3D map_size =3D map_offset =3D map_readonly =3D =
map_start_searched =3D 0;=0A=
=0A=
		ret =3D resource_string_value("map", i, "at", &tmpstr);=0A=
		/* Check if my provider */=0A=
		if (ret || strcmp(pp->name, tmpstr))=0A=
			continue;=0A=
=0A=
		ret =3D resource_string_value("map", i, "name", &map_name);=0A=
		/* No name or error read name */=0A=
		if (ret)=0A=
			continue;=0A=
=0A=
		ret =3D resource_string_value("map", i, "start", &tmpstr);=0A=
		/* No start or error read */=0A=
		if (ret)=0A=
			continue;=0A=
		if (strncmp(tmpstr, "search", 6) =3D=3D 0) {=0A=
			ret =3D resource_string_value("map", i, "searchkey", &search_key);=0A=
			if (ret)=0A=
				continue;=0A=
=0A=
			search_start =3D 0;=0A=
			search_step =3D MAP_SEARCH_STEP_DEF;=0A=
			resource_quad_t_value("map", i, "searchstart", &search_start);=0A=
			resource_quad_t_value("map", i, "searchstep", &search_step);=0A=
			map_start_searched =3D 1;=0A=
=0A=
			map_start =3D g_map_search_key(cp, sectorsize, search_start, =
search_step, search_key, strlen(search_key));=0A=
			/* is search failed? */=0A=
			if (search_start > map_start)=0A=
				ret =3D 1;=0A=
		} else=0A=
			ret =3D resource_quad_t_value("map", i, "start", &map_start);=0A=
		if (ret)=0A=
			continue;=0A=
=0A=
=0A=
		ret =3D resource_string_value("map", i, "end", &tmpstr);=0A=
		/* No start or error read */=0A=
		if (ret)=0A=
			continue;=0A=
		if (strncmp(tmpstr, "search", 6) =3D=3D 0) {=0A=
			ret =3D resource_string_value("map", i, "searchkey", &search_key);=0A=
			if (ret)=0A=
				continue;=0A=
=0A=
			search_step =3D MAP_SEARCH_STEP_DEF;=0A=
			if (map_start_searched) {=0A=
				/* we found key for start, end will see in next "step" offset */=0A=
				search_start =3D (map_start + search_step);=0A=
			}else{=0A=
				search_start =3D 0;=0A=
				resource_quad_t_value("map", i, "searchstart", &search_start);=0A=
			}=0A=
			resource_quad_t_value("map", i, "searchstep", &search_step);=0A=
=0A=
			map_end =3D g_map_search_key(cp, sectorsize, search_start, =
search_step, search_key, strlen(search_key));=0A=
			/* is search failed? */=0A=
			if (search_start > map_start)=0A=
				ret =3D 1;=0A=
		} else=0A=
			ret =3D resource_quad_t_value("map", i, "end", &map_end);=0A=
=0A=
		map_size =3D (map_end - map_start);=0A=
=0A=
		/* end is 0 or size is 0, No MAP - so next */=0A=
		if (ret || map_end =3D=3D 0 || map_size =3D=3D 0)=0A=
			continue;=0A=
		if (map_offset > map_size) {=0A=
			printf("GEOM_MAP: /dev/%s: offset(%jx) > size(%jx) for \"%s\"\n", =
pp->name, map_offset, map_size, map_name);=0A=
			continue;=0A=
		}=0A=
=0A=
		resource_quad_t_value("map", i, "offset", &map_offset);=0A=
		resource_int_value("map", i, "readonly", &map_readonly);=0A=
=0A=
		/* strip dev name: pp->name =3D "flash/spi0" -> tmpstr =3D "spi0" */=0A=
		for (tmpstr =3D (pp->name + strlen(pp->name)); tmpstr > pp->name && =
tmpstr[0] !=3D '/'; tmpstr --);=0A=
		if (tmpstr[0] =3D=3D '/')=0A=
			tmpstr ++;=0A=
=0A=
		ret =3D g_slice_config(gp, idx, G_SLICE_CONFIG_SET, (map_start + =
map_offset), (map_size - map_offset), sectorsize, "map/%s%s", tmpstr, =
map_name);=0A=
		if (ret) {=0A=
			printf("GEOM_MAP: /dev/%s: g_slice_config returns %d for \"%s\"\n", =
pp->name, ret, map_name);=0A=
		}else{=0A=
			sc->entry[idx] =3D map_offset;=0A=
			sc->dsize[idx] =3D (map_size - map_offset);=0A=
			sc->readonly[idx] =3D map_readonly;=0A=
			idx ++;=0A=
=0A=
			printf("GEOM_MAP: /dev/%s: 0x%08jx-0x%08jx, offset=3D0x%jx, %s, =
size=3D%ju bytes at: \"/dev/map/%s%s\"\n",=0A=
				pp->name, map_start, map_end, map_offset, (map_readonly? =
"R/O":"R/W"), map_size, tmpstr, map_name);=0A=
		}=0A=
	}/* for (i =3D 0; i < MAP_MAXSLICE; i++) */=0A=
=0A=
	return(idx);=0A=
}=0A=
=0A=
=0A=
=0A=
static struct g_geom *=0A=
g_map_taste(struct g_class *mp, struct g_provider *pp, int insist)=0A=
{=0A=
	struct g_geom *gp;=0A=
	struct g_consumer *cp;=0A=
	struct g_map_softc *sc;=0A=
	u_int idx =3D 0;=0A=
=0A=
=0A=
	g_trace(G_T_TOPOLOGY, "map_taste(%s,%s)", mp->name, pp->name);=0A=
	g_topology_assert();=0A=
	if (!strcmp(pp->geom->class->name, MAP_CLASS_NAME))=0A=
		return (NULL);=0A=
=0A=
	gp =3D g_slice_new(mp, MAP_MAXSLICE, pp, &cp, &sc, sizeof(*sc), =
g_map_start);=0A=
	if (gp =3D=3D NULL)=0A=
		return (NULL);=0A=
=0A=
	/* interpose our access method */=0A=
	sc->parent_access =3D gp->access;=0A=
	gp->access =3D g_map_access;=0A=
=0A=
	idx +=3D g_map_load_hints(cp, idx);=0A=
=0A=
#if !defined(GEOM_MAP_NO_REDBOOT)=0A=
	idx +=3D g_map_load_fis(cp, idx);=0A=
#endif=0A=
=0A=
	if (idx && bootverbose)=0A=
		printf("GEOM_MAP: /dev/%s: mediasize=3D%ju, secsize=3D%d, =
blksize=3D%d\n",=0A=
		    pp->name, pp->mediasize, pp->sectorsize, pp->stripesize);=0A=
=0A=
=0A=
	g_access(cp, -1, 0, 0);=0A=
	if (LIST_EMPTY(&gp->provider)) {=0A=
		g_slice_spoiled(cp);=0A=
		return (NULL);=0A=
	}=0A=
	return (gp);=0A=
}=0A=
=0A=
static void=0A=
g_map_config(struct gctl_req *req, struct g_class *mp, const char *verb)=0A=
{=0A=
	struct g_geom  *gp;=0A=
=0A=
	g_topology_assert();=0A=
	gp =3D gctl_get_geom(req, mp, "geom");=0A=
	if (gp =3D=3D NULL)=0A=
		return;=0A=
	gctl_error(req, "Unknown verb");=0A=
}=0A=
=0A=
static struct g_class g_map_class =3D {=0A=
	.name		=3D MAP_CLASS_NAME,=0A=
	.version	=3D G_VERSION,=0A=
	.taste		=3D g_map_taste,=0A=
	.dumpconf	=3D g_map_dumpconf,=0A=
	.ctlreq	=3D g_map_config,=0A=
	.ioctl		=3D g_map_ioctl,=0A=
};=0A=
DECLARE_GEOM_CLASS(g_map_class, g_map);=0A=

------=_NextPart_000_0076_01CBF272.D99FC070
Content-Type: text/plain;
	name="options_add_geom_map.txt"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="options_add_geom_map.txt"

--- /usr/src/sys/conf/options_orig      2011-04-04 02:38:46.000000000 =
+0900=0A=
+++ /usr/src/sys/conf/options   2011-04-03 06:18:26.000000000 +0900=0A=
@@ -1,4 +1,4 @@=0A=
-# $FreeBSD: src/sys/conf/options,v 1.687.2.11 2011/03/27 00:42:28 kib =
Exp $=0A=
+# $FreeBSD: src/sys/conf/options,v 1.687.2.10 2010/07/09 08:48:51 ae =
Exp $=0A=
 #=0A=
 #        On the handling of kernel options=0A=
 #=0A=
@@ -99,6 +99,8 @@=0A=
 GEOM_PART_MBR  opt_geom.h=0A=
 GEOM_PART_PC98 opt_geom.h=0A=
 GEOM_PART_VTOC8        opt_geom.h=0A=
+GEOM_MAP       opt_geom.h=0A=
+GEOM_MAP_NO_REDBOOT opt_geom.h=0A=
 GEOM_PC98      opt_geom.h=0A=
 GEOM_RAID3     opt_geom.h=0A=
 GEOM_SHSEC     opt_geom.h=0A=
=0A=

------=_NextPart_000_0076_01CBF272.D99FC070--




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4d98b30d.581ce30a.3a77.ffffc4d6>