merge geom redboot and map
rozhuk.im at gmail.com
rozhuk.im at gmail.com
Sun Apr 3 17:49:04 UTC 2011
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 #
options GEOM_MAP_NO_REDBOOT # turn off redboot/fis support
Static mappings in hints:
===========================================================
# 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 = "flash/spi0"
hint.map.0.start = 0x00000000
hint.map.0.end = 0x00030000
hint.map.0.name = "bootldr"
hint.map.0.readonly =1
hint.map.1.at = "flash/spi0"
hint.map.1.start = 0x00030000
hint.map.1.end = 0x00040000
hint.map.1.name = "bootldr_env"
hint.map.1.readonly =1
hint.map.2.at = "flash/spi0"
hint.map.2.start = 0x00040000
hint.map.2.end = 0x00240000
hint.map.2.name = "kernel"
hint.map.2.readonly =0
hint.map.3.at = "flash/spi0"
hint.map.3.start = 0x00240000
hint.map.3.end = 0x00800000
hint.map.3.name = "rootfs"
hint.map.3.readonly =0
===========================================================
Boot log:
===========================================================
...
GEOM_MAP: /dev/flash/spi0: 0x00000000-0x00030000, offset=0x0, R/O,
size=196608 bytes at: "/dev/map/spi0bootldr"
GEOM_MAP: /dev/flash/spi0: 0x00030000-0x00040000, offset=0x0, R/O,
size=65536 bytes at: "/dev/map/spi0bootldr_env"
GEOM_MAP: /dev/flash/spi0: 0x00040000-0x00240000, offset=0x0, R/W,
size=2097152 bytes at: "/dev/map/spi0kernel"
GEOM_MAP: /dev/flash/spi0: 0x00240000-0x00800000, offset=0x0, R/W,
size=6029312 bytes at: "/dev/map/spi0rootfs"
GEOM_MAP: /dev/flash/spi0: FIS/RedBoot not exist, incompatible blksize=0
GEOM_MAP: /dev/flash/spi0: mediasize=8388608, secsize=65536, blksize=0
...
GEOM_MAP: /dev/da0: FIS/RedBoot not exist, incompatible blksize=0
GEOM_MAP: /dev/da0p1: FIS/RedBoot not exist, incompatible blksize=0
GEOM_MAP: /dev/gpt/Documental: FIS/RedBoot not exist, incompatible blksize=0
GEOM_MAP: /dev/gptid/ca70d533-5759-11e0-b900-001a4d559a42: FIS/RedBoot not
exist, incompatible blksize=0
Mounting local file systems:GEOM_MAP: /dev/md0: FIS/RedBoot not exist,
incompatible blksize=0
GEOM_MAP: /dev/ufsid/4d98a59e587419bf: FIS/RedBoot not exist, incompatible
blksize=0
GEOM_MAP: /dev/md0: FIS/RedBoot not exist, incompatible blksize=0
GEOM_MAP: /dev/ufsid/4d98a967c292e50d: FIS/RedBoot not exist, incompatible
blksize=0
GEOM_MAP: /dev/md1: FIS/RedBoot not exist, incompatible blksize=0
GEOM_MAP: /dev/md1: FIS/RedBoot not exist, incompatible blksize=0
GEOM_MAP: /dev/ufsid/4d98a968674909d4: FIS/RedBoot not exist, incompatible
blksize=0
...
===========================================================
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=156130
--
Rozhuk Ivan
> -----Original Message-----
> From: Aleksandr Rybalko [mailto:ray at ddteam.net]
> Sent: Thursday, March 31, 2011 5:28 AM
> To: Rozhuk.IM at gmail.com
> Cc: rozhuk.im at gmail.com; 'Warner Losh'; freebsd-arm at freebsd.org;
> freebsd-geom at freebsd.org
> Subject: Re: merge geom redboot and map
>
> Hi all,
>
> On Thu, 31 Mar 2011 04:19:11 +0900
> rozhuk.im at gmail.com wrote:
>
> >
> > > > 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. ?
>
> 3. /dev/flash/spi0kernel, /dev/flash/spi0rootfs, ...
>
> IMO, /dev/map/ more generic :)
>
> >
> > _______________________________________________
> > freebsd-arm at freebsd.org mailing list
> > http://lists.freebsd.org/mailman/listinfo/freebsd-arm
> > To unsubscribe, send any mail to "freebsd-arm-
> unsubscribe at freebsd.org"
>
> P.S.
>
> 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.
>
> WBW
> --
> Aleksandr Rybalko <ray at ddteam.net>
-------------- next part --------------
--- /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;
}
+
+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 = 0;
+ error = resource_find(&line, NULL, name, &unit, resname, NULL,
+ NULL, NULL, NULL, NULL, NULL, &str);
+ if (error)
+ return error;
+ if (*str == '\0')
+ return EFTYPE;
+ val = strtoq(str, &op, 0);
+ if (*op != '\0')
+ return EFTYPE;
+ *result = 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);
-------------- next part --------------
/*-
* Copyright (c) 2009 Aleksandr Rybalko AKA Alex RAY, DDTeam.net
* based on geom_redboot.c
* Copyright (c) 2009 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
* redistribution must be conditioned upon including a substantially
* similar Disclaimer requirement for further binary redistribution.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/errno.h>
#include <sys/endian.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/fcntl.h>
#include <sys/malloc.h>
#include <sys/bio.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/sbuf.h>
#include <geom/geom.h>
#include <geom/geom_slice.h>
#include "opt_geom.h"
#define MAP_CLASS_NAME "MAP"
#define MAP_MAXSLICE 64
#define MAP_SEARCH_KEY_LEN_MAX 255
#define MAP_SEARCH_STEP_DEF 0x10000U
struct g_map_softc {
g_access_t *parent_access;
off_t entry[MAP_MAXSLICE]; /* offset in image for entry point */
off_t dsize[MAP_MAXSLICE]; /* data size in bytes */
u_int readonly[MAP_MAXSLICE];
};
#if !defined(GEOM_MAP_NO_REDBOOT)
struct fis_image_desc {
uint8_t name [16]; /* null-terminated name */
uint32_t offset; /* offset in flash */
uint32_t addr; /* address in memory */
uint32_t size; /* image size in bytes */
uint32_t entry; /* offset in image for entry point */
uint32_t dsize; /* data size in bytes */
uint8_t pad[256-(16+7*sizeof(uint32_t)+sizeof(void*))];
struct fis_image_desc *next; /* linked list (in memory) */
uint32_t dsum; /* descriptor checksum */
uint32_t fsum; /* checksum over image data */
};
#define FISDIR_NAME "FIS directory"
#define REDBCFG_NAME "RedBoot config"
#define REDBOOT_NAME "RedBoot"
#endif /* !defined(GEOM_MAP_NO_REDBOOT) */
static int
g_map_ioctl(struct g_provider *pp, u_long cmd, void *data, int fflag, struct thread *td)
{
return (ENOIOCTL);
}
static int
g_map_access(struct g_provider *pp, int dread, int dwrite, int dexcl)
{
struct g_geom *gp = pp->geom;
struct g_slicer *gsp = gp->softc;
struct g_map_softc *sc = gsp->softc;
if (dwrite > 0 && sc->readonly[pp->index])
return (EPERM);
return (sc->parent_access(pp, dread, dwrite, dexcl));
}
static int
g_map_start(struct bio *bp)
{
struct g_provider *pp;
struct g_geom *gp;
struct g_map_softc *sc;
struct g_slicer *gsp;
int idx;
pp = bp->bio_to;
idx = pp->index;
gp = pp->geom;
gsp = gp->softc;
sc = gsp->softc;
if (bp->bio_cmd == BIO_GETATTR) {
if (g_handleattr_off_t(bp, MAP_CLASS_NAME "::entry", sc->entry[idx]))
return (1);
if (g_handleattr_off_t(bp, MAP_CLASS_NAME "::dsize", sc->dsize[idx]))
return (1);
}
return (0);
}
static void
g_map_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp,
struct g_consumer *cp __unused, struct g_provider *pp)
{
struct g_map_softc *sc;
struct g_slicer *gsp;
gsp = gp->softc;
sc = gsp->softc;
g_slice_dumpconf(sb, indent, gp, cp, pp);
if (pp != NULL) {
if (indent == NULL) {
sbuf_printf(sb, " entry %jd", sc->entry[pp->index]);
sbuf_printf(sb, " dsize %jd", sc->dsize[pp->index]);
sbuf_printf(sb, " readonly %u", sc->readonly[pp->index]);
} else {
sbuf_printf(sb, "%s<entry>%jd</entry>\n", indent, sc->entry[pp->index]);
sbuf_printf(sb, "%s<dsize>%jd</dsize>\n", indent, sc->dsize[pp->index]);
sbuf_printf(sb, "%s<readonly>%u</readonly>\n", indent, sc->readonly[pp->index]);
}
}
}
#include <sys/ctype.h>
#if !defined(GEOM_MAP_NO_REDBOOT)
static void
g_map_print_redboot(int i, struct fis_image_desc *fd)
{
printf("[%2d] \"%-15.15s\" %08x:%08x", i, fd->name, fd->offset, fd->size);
printf(" addr %08x entry %08x\n", fd->addr, fd->entry);
printf(" dsize 0x%x dsum 0x%x fsum 0x%x\n", fd->dsize, fd->dsum, fd->fsum);
}
static int
nameok(const char name[16])
{
int i;
/* descriptor names are null-terminated printable ascii */
for (i = 0; i < 15; i++)
if (!isprint(name[i]))
break;
return (name[i] == '\0');
}
static struct fis_image_desc *
parse_fis_directory(u_char *buf, size_t bufsize, off_t offset, uint32_t offmask)
{
#define match(a,b) (bcmp(a, b, sizeof(b)-1) == 0)
struct fis_image_desc *fd, *efd;
struct fis_image_desc *fisdir, *redbcfg;
struct fis_image_desc *head, **tail;
int i;
fd = (struct fis_image_desc *)buf;
efd = fd + (bufsize / sizeof(struct fis_image_desc));
#if 0
/*
* Find the start of the FIS table.
*/
while (fd < efd && fd->name[0] != 0xff)
fd++;
if (fd == efd)
return (NULL);
if (bootverbose)
printf("RedBoot FIS table starts at 0x%jx\n",
offset + fd - (struct fis_image_desc *) buf);
#endif
/*
* Scan forward collecting entries in a list.
*/
fisdir = redbcfg = NULL;
*(tail = &head) = NULL;
for (i = 0; fd < efd; i++, fd++) {
if (fd->name[0] == 0xff)
continue;
if (match(fd->name, FISDIR_NAME))
fisdir = fd;
else if (match(fd->name, REDBCFG_NAME))
redbcfg = fd;
if (nameok(fd->name)) {
/*
* NB: flash address includes platform mapping;
* strip it so we have only a flash offset.
*/
fd->offset &= offmask;
if (bootverbose)
g_map_print_redboot(i, fd);
*tail = fd;
*(tail = &fd->next) = NULL;
}
}
if (fisdir == NULL) {
if (bootverbose)
printf("No RedBoot FIS table located at %ju\n", offset);
return (NULL);
}
if (redbcfg != NULL &&
fisdir->offset + fisdir->size == redbcfg->offset) {
/*
* Merged FIS/RedBoot config directory.
*/
if (bootverbose)
printf("FIS/RedBoot merged at 0x%jx (not yet)\n",
offset + fisdir->offset);
/* XXX */
}
return head;
#undef match
}
/* load maps from hints */
static u_int
g_map_load_fis(struct g_consumer *cp, u_int idx)
{
struct g_geom *gp;
struct g_provider *pp;
struct g_slicer *gsp;
struct g_map_softc *sc;
struct fis_image_desc *fd, *head;
u_char *buf;
int error;
u_int sectorsize, blksize; /* NB: flash block size stored as stripesize */
uint32_t offmask;
off_t offset;
gp = cp->geom;
pp = cp->provider;
gsp = gp->softc;
sc = gsp->softc;
sectorsize = cp->provider->sectorsize;
if (sectorsize < sizeof(struct fis_image_desc) ||
(sectorsize % sizeof(struct fis_image_desc))) {
if (bootverbose)
printf("GEOM_MAP: /dev/%s: FIS/RedBoot not exist, incompatible sectorsize=%u\n", pp->name, sectorsize);
return (0);
}
blksize = cp->provider->stripesize;
if (blksize == 0) {
if (bootverbose)
printf("GEOM_MAP: /dev/%s: FIS/RedBoot not exist, incompatible blksize=%u\n", pp->name, blksize);
return (0);
}
if (powerof2(cp->provider->mediasize))
offmask = cp->provider->mediasize-1;
else
offmask = 0xffffffff; /* XXX */
offset = (cp->provider->mediasize - blksize);
g_topology_unlock();
again:
head = NULL;
buf = g_read_data(cp, offset, blksize, NULL);
if (buf != NULL)
head = parse_fis_directory(buf, blksize, offset, offmask);
if (head == NULL && offset != 0) {
if (bootverbose)
printf("GEOM_MAP: /dev/%s: FIS/RedBoot table not found in last block, try firast block\n", pp->name);
if (buf != NULL)
g_free(buf);
offset = 0; /* check the front */
goto again;
}
g_topology_lock();
if (head == NULL) {
if (bootverbose)
printf("GEOM_MAP: /dev/%s: FIS/RedBoot not found on device\n", pp->name);
if (buf != NULL)
g_free(buf);
return (0);
}
/* Craft a slice for each entry. */
for (fd = head; fd != NULL; fd = fd->next) {
if (fd->name[0] == '\0')
continue;
error = g_slice_config(gp, idx, G_SLICE_CONFIG_SET, fd->offset, fd->size, sectorsize, "redboot/%s", fd->name);
if (error) {
printf("GEOM_MAP: /dev/%s: g_slice_config returns %d for \"%s\"\n", pp->name, error, fd->name);
}else{
sc->entry[idx] = fd->entry;
sc->dsize[idx] = fd->dsize;
/* disallow writing hard-to-recover entries */
sc->readonly[idx] = (strcmp(fd->name, FISDIR_NAME) == 0) || (strcmp(fd->name, REDBOOT_NAME) == 0);
idx ++;
printf("GEOM_MAP: /dev/%s: 0x%08x-0x%08x, offset=0x%x, %s, size=%ul bytes at: \"/dev/redboot/%s\"\n",
pp->name, fd->addr, (fd->addr + fd->size), fd->entry, (sc->readonly[idx]? "R/O":"R/W"), fd->size, fd->name);
}
}
g_free(buf);
return(idx);
}
#endif /* !defined(GEOM_MAP_NO_REDBOOT) */
/* search given key on some geom */
static off_t
g_map_search_key(struct g_consumer *cp, u_int sectorsize, off_t from, off_t step, const char *key, u_int key_len)
{
struct g_provider *pp;
off_t ret = 0, i, mediasize, read_len;
u_int c;
char key_mask[MAP_SEARCH_KEY_LEN_MAX];
u_char *buf;
pp = cp->provider;
key_len = min(MAP_SEARCH_KEY_LEN_MAX, key_len);
read_len = roundup(key_len, sectorsize);
mediasize = cp->provider->mediasize;
if (bootverbose)
printf("GEOM_MAP: /dev/%s: searchkey=\"%s\", from=0x%jx, step=0x%jx...", pp->name, key, from, step);
g_topology_unlock();
for (i = from; i < mediasize && ret == 0; i += step) {
buf = g_read_data(cp, rounddown(i, sectorsize), read_len, NULL);
/* read ok? */
if (buf == NULL)
break;
/* Wildcard, replace '.' with byte from data */
bcopy(key, key_mask, key_len);
for (c = 0; c < key_len; c++)
if (key_mask[c] == '.')
key_mask[c] = ((char *)(buf + (i % sectorsize)))[c];
if (bcmp( (buf + (i % sectorsize)), key_mask, key_len) == 0)
ret = i;
g_free(buf);
}
g_topology_lock();
if (bootverbose) {
if (ret)
printf("found at 0x%jx\n", ret);
else
printf("NOT found!\n");
}
return(ret);
}
/* load maps from hints */
static u_int
g_map_load_hints(struct g_consumer *cp, u_int idx)
{
struct g_geom *gp;
struct g_provider *pp;
struct g_slicer *gsp;
struct g_map_softc *sc;
const char *map_name, *tmpstr, *search_key;
off_t map_start, map_end, map_size, map_offset, search_start, search_step;
u_int i, sectorsize, map_readonly, map_start_searched;
int ret;
gp = cp->geom;
pp = cp->provider;
gsp = gp->softc;
sc = gsp->softc;
sectorsize = cp->provider->sectorsize;
for (i = 0; i < MAP_MAXSLICE; i++) {
map_start = map_end = map_size = map_offset = map_readonly = map_start_searched = 0;
ret = resource_string_value("map", i, "at", &tmpstr);
/* Check if my provider */
if (ret || strcmp(pp->name, tmpstr))
continue;
ret = resource_string_value("map", i, "name", &map_name);
/* No name or error read name */
if (ret)
continue;
ret = resource_string_value("map", i, "start", &tmpstr);
/* No start or error read */
if (ret)
continue;
if (strncmp(tmpstr, "search", 6) == 0) {
ret = resource_string_value("map", i, "searchkey", &search_key);
if (ret)
continue;
search_start = 0;
search_step = MAP_SEARCH_STEP_DEF;
resource_quad_t_value("map", i, "searchstart", &search_start);
resource_quad_t_value("map", i, "searchstep", &search_step);
map_start_searched = 1;
map_start = g_map_search_key(cp, sectorsize, search_start, search_step, search_key, strlen(search_key));
/* is search failed? */
if (search_start > map_start)
ret = 1;
} else
ret = resource_quad_t_value("map", i, "start", &map_start);
if (ret)
continue;
ret = resource_string_value("map", i, "end", &tmpstr);
/* No start or error read */
if (ret)
continue;
if (strncmp(tmpstr, "search", 6) == 0) {
ret = resource_string_value("map", i, "searchkey", &search_key);
if (ret)
continue;
search_step = MAP_SEARCH_STEP_DEF;
if (map_start_searched) {
/* we found key for start, end will see in next "step" offset */
search_start = (map_start + search_step);
}else{
search_start = 0;
resource_quad_t_value("map", i, "searchstart", &search_start);
}
resource_quad_t_value("map", i, "searchstep", &search_step);
map_end = g_map_search_key(cp, sectorsize, search_start, search_step, search_key, strlen(search_key));
/* is search failed? */
if (search_start > map_start)
ret = 1;
} else
ret = resource_quad_t_value("map", i, "end", &map_end);
map_size = (map_end - map_start);
/* end is 0 or size is 0, No MAP - so next */
if (ret || map_end == 0 || map_size == 0)
continue;
if (map_offset > map_size) {
printf("GEOM_MAP: /dev/%s: offset(%jx) > size(%jx) for \"%s\"\n", pp->name, map_offset, map_size, map_name);
continue;
}
resource_quad_t_value("map", i, "offset", &map_offset);
resource_int_value("map", i, "readonly", &map_readonly);
/* strip dev name: pp->name = "flash/spi0" -> tmpstr = "spi0" */
for (tmpstr = (pp->name + strlen(pp->name)); tmpstr > pp->name && tmpstr[0] != '/'; tmpstr --);
if (tmpstr[0] == '/')
tmpstr ++;
ret = g_slice_config(gp, idx, G_SLICE_CONFIG_SET, (map_start + map_offset), (map_size - map_offset), sectorsize, "map/%s%s", tmpstr, map_name);
if (ret) {
printf("GEOM_MAP: /dev/%s: g_slice_config returns %d for \"%s\"\n", pp->name, ret, map_name);
}else{
sc->entry[idx] = map_offset;
sc->dsize[idx] = (map_size - map_offset);
sc->readonly[idx] = map_readonly;
idx ++;
printf("GEOM_MAP: /dev/%s: 0x%08jx-0x%08jx, offset=0x%jx, %s, size=%ju bytes at: \"/dev/map/%s%s\"\n",
pp->name, map_start, map_end, map_offset, (map_readonly? "R/O":"R/W"), map_size, tmpstr, map_name);
}
}/* for (i = 0; i < MAP_MAXSLICE; i++) */
return(idx);
}
static struct g_geom *
g_map_taste(struct g_class *mp, struct g_provider *pp, int insist)
{
struct g_geom *gp;
struct g_consumer *cp;
struct g_map_softc *sc;
u_int idx = 0;
g_trace(G_T_TOPOLOGY, "map_taste(%s,%s)", mp->name, pp->name);
g_topology_assert();
if (!strcmp(pp->geom->class->name, MAP_CLASS_NAME))
return (NULL);
gp = g_slice_new(mp, MAP_MAXSLICE, pp, &cp, &sc, sizeof(*sc), g_map_start);
if (gp == NULL)
return (NULL);
/* interpose our access method */
sc->parent_access = gp->access;
gp->access = g_map_access;
idx += g_map_load_hints(cp, idx);
#if !defined(GEOM_MAP_NO_REDBOOT)
idx += g_map_load_fis(cp, idx);
#endif
if (idx && bootverbose)
printf("GEOM_MAP: /dev/%s: mediasize=%ju, secsize=%d, blksize=%d\n",
pp->name, pp->mediasize, pp->sectorsize, pp->stripesize);
g_access(cp, -1, 0, 0);
if (LIST_EMPTY(&gp->provider)) {
g_slice_spoiled(cp);
return (NULL);
}
return (gp);
}
static void
g_map_config(struct gctl_req *req, struct g_class *mp, const char *verb)
{
struct g_geom *gp;
g_topology_assert();
gp = gctl_get_geom(req, mp, "geom");
if (gp == NULL)
return;
gctl_error(req, "Unknown verb");
}
static struct g_class g_map_class = {
.name = MAP_CLASS_NAME,
.version = G_VERSION,
.taste = g_map_taste,
.dumpconf = g_map_dumpconf,
.ctlreq = g_map_config,
.ioctl = g_map_ioctl,
};
DECLARE_GEOM_CLASS(g_map_class, g_map);
-------------- next part --------------
--- /usr/src/sys/conf/options_orig 2011-04-04 02:38:46.000000000 +0900
+++ /usr/src/sys/conf/options 2011-04-03 06:18:26.000000000 +0900
@@ -1,4 +1,4 @@
-# $FreeBSD: src/sys/conf/options,v 1.687.2.11 2011/03/27 00:42:28 kib Exp $
+# $FreeBSD: src/sys/conf/options,v 1.687.2.10 2010/07/09 08:48:51 ae Exp $
#
# On the handling of kernel options
#
@@ -99,6 +99,8 @@
GEOM_PART_MBR opt_geom.h
GEOM_PART_PC98 opt_geom.h
GEOM_PART_VTOC8 opt_geom.h
+GEOM_MAP opt_geom.h
+GEOM_MAP_NO_REDBOOT opt_geom.h
GEOM_PC98 opt_geom.h
GEOM_RAID3 opt_geom.h
GEOM_SHSEC opt_geom.h
More information about the freebsd-arm
mailing list